JavaScript Editor JavaScript Debugger     JavaScript Editor 



Team LiB
Previous Section Next Section

One-Way Communication

The simplest form of communication is a one-way notification from a script in the browser to the Web server indicating that some event has occurred. For example, suppose you’re showing the user a list of products and asking the user to rate them. It would be tedious if every time the user rated a product a form was submitted and the page was reloaded. Users would quickly lose interest. You could let the user rate a bunch of products and then submit a form when they’re done, but doing so risks losing the ratings of users who forget to submit, and still incurs the round-trip overhead of the submission itself. What’s needed is a fast, easy way for the page to communicate rating messages to the Web server.

If you think about the elements available in (X)HTML, you’ll realize that many have a src or similar attribute that can be specified dynamically. Since, when you set an element’s src with JavaScript, the browser automatically loads the specified resource, this is a perfect vehicle for one-way (client to server) communication.

When you wish to send a message to the server, construct the message as a series of CGI parameters, append these CGI parameters to a URL targeting your server, and set the source of the object you’re using as the transport mechanism to this URL. When a request comes into your server for the given URL, the server parses the parameters and presumably does something with the information, for example, updating a database with the customer’s rating. These steps are outlined next:

  1. Construct query parameters (e.g., productid=2158&rating=5&user=Bob).

  2. Append parameters to a predetermined URL (e.g., http://www.example.com/setrating.cgi?productid=2158&rating=5&user=Bob ).

  3. Set the source of an element to this URL causing the browser to fetch it.

  4. Server receives request and invokes handler (e.g., setrating.cgi).

  5. Handler parses parameters and uses them.

  6. Handler returns a response (which is probably ignored).

All that remains is finding an appropriate (X)HTML element with which the communication can be realized.

Images

By far the most common vehicle used for one-way communication is images. You don’t even have to use <<img>>s embedded in the page; in fact, it’s preferable not to. Since you don’t intend to actually download or display an image, you can create an Image object, use it, and then throw it away. Consider the following document fragment:

<<script type="text/javascript">>
var commandURL = "http://demos.javascriptref.com/setrating.php?";
function sendURL(url) 
{
  var img = new Image();
  img.src = url;
}
function sendRating(productid, rating, user) 
{
  var params = "productid=" + productid;
  params += "&rating=" + rating;
  params += "&user=" + user;
  sendURL(commandURL + params);
  return false;
}
<</script>>
<<!-- ... -->>
Rate this item:
<<form action="#" method="get">>
  <<input type="button" value="Horrible!" onclick="return sendRating(2158, 1,
 'Bob');" />>
  <<input type="button" value="OK" onclick="return sendRating(2158, 2,
 'Bob');" />>
  <<input type="button" value="Great!" onclick="return sendRating(2158, 3,
 'Bob');" />>
<</form>>
Note 

Don’t think that because we are using form buttons here that this is a traditional style communication. In fact, we could have used just about any object we could click by attaching an onclick, including links (<<a>>) or even structural elements like <<div>> or <<p>>, but we used form buttons since the user would feel they were clickable!

We’ve omitted the server-side script that presumably handles these requests. You could write a simple CGI that returns a 1-pixel-by-1-pixel image if you like, or you could just return any old content you like. Since we’re not doing anything with the result, we don’t even care if the server returns an error. In fact, you don’t even have to have a setrating.cgi to handle this request. Instead, you could just let the server return a 404 and extract the information from your logs. These requests will result in log lines that look something like this:

www.example.com - - [19/Mar/2004:21:05:29 -0800] "GET
 /setrating.cgi?productid=2158&rating=1&user=fritz HTTP/1.0" 403 305 

You could easily write a script to comb your logs for these messages, parse them, and do with the information what you will (e.g., enter it in a database).

Note 

In the preceding example, you don’t necessarily have to pass user information via the CGI parameters. If you use cookies for authentication, the cookie will be sent as usual along with the request, and the server-side script can extract the user’s identity from the cookie.

A more elegant approach would be to have your server-side program record the data and then actually pass back a proper response code to the browser. In this case, we could return a 204 HTTP Response code indicating no content so that the browser wouldn’t think anything was amiss. While this would appear the cleaner way to do things, it isn’t really necessary. However, don’t play fast and loose with HTTP; there are significant pitfalls to avoid.

Encoding Parameters

Some characters are illegal in URLs, and Web servers will often choke if they are included. For example, you can’t have carriage returns or backspaces in a URL. If the parameters you wish to pass the server might include problematic characters, you need to encode them. Encoding replaces problematic characters with their ASCII values as a hexadecimal escape sequence, for example, %0D for a new line. The Web server automatically decodes URLs it receives and makes the decoded parameters available to CGIs and the like.

To encode a string, simply call encode() on it. We can rewrite the parameter setup code from the previous example in this way:

var params = "productid=" + encode(productid);
params += "&rating=" + encode(rating);
params += "&user=" + encode(user);

It’s almost always a good idea to encode your parameters, even if you don’t think there’s a chance for problematic characters to sneak in.

Other Objects

There’s no particular reason to use Images for this RPC other than that they’re widely supported and simple to script. Any (X)HTML element that has a property that can be set to a URL will work. One common technique is to use a single hidden <<iframe>> for communication. Whenever you wish to send a message to the server, set the <<iframe>>‘s src to the message URL. We’ll see that <<iframe>>s are more commonly used for two-way communication in a later section.

Redirects

The HTTP response code 204 “No Content,” which we alluded to earlier, is a very useful, but not well-known feature of the HTTP protocol. When a server returns a 204 (as opposed to, say, a 200 “OK” or 404 “File not found”), it is a signal to the browser that for some reason the server doesn’t have any data to send in response, so the browser should take no action. Even though the browser makes the request to the server, pointing your browser at a URL that returns a 204 has no visual effect: the browser appears to do nothing.

We can use HTTP 204 response codes to our advantage by making an RPC call via a JavaScript redirect to a URL that returns a 204. To set this up, configure your Web server (or a cgi script) to return a 204 for a particular URL, for example, setrating.cgi. Then write your JavaScript to redirect the browser to this URL with the parameters of the message you wish to send.

The only part of the previous example that needs to be changed to use this technique is the sendURL() function, which will now redirect instead of loading a fake image:

function sendURL(url) 
{
  window.location = url;
}

To send an RPC, the JavaScript constructs the URL and then redirects the browser to it. When the server receives the request, it returns a 204, which causes the browser to cancel navigation since there’s no page to navigate to. The user is none the wiser, though some browsers may show a slight indication of browser activity hinting at the behind-the-scenes transmission.

When many developers first encounter this technique, they’re often quite skeptical that it could actually work in a wide array of browsers. The authors have verified that it works in Internet Explorer 3 and later, Netscape 4 and later, and Mozilla-based browsers, and we wouldn’t be surprised to hear if it was nearly universally supported.

One advantage this technique has over image-based techniques is that it is often perceived by users as less “scary.” Many users rightly worry about “Web bugs,” invisible images placed on pages that are fetched from third-party servers in order to track browsing habits. Some users examining the page are probably more likely to feel comfortable with a redirect than an undercover image fetch.

A disadvantage of this technique is that if the user’s browser doesn’t properly implement HTTP, it could actually navigate to a blank page as a result of the redirect. Though this is extremely uncommon, some developers may feel it is a compelling reason to use images instead.


Team LiB
Previous Section Next Section


JavaScript Editor JavaScript Debugger     JavaScript Editor


©