Article
No-Refresh Links
Page: 1 2
So How's It Done?
Then Fabio Dias wrote to me on Christmas Day (how appropriate!) with a promising tidbit he found hiding in the Hypertext Transfer Protocol (HTTP) Specification. For those who don’t know, HTTP is the protocol used for communication between Web browsers and Web servers. Basically, HTTP communication is initiated by a browser making a page request. The Web server then answers that request, first with a code that indicates the type of response, then with the HTML content for the new page if appropriate. The most common response code is 200, meaning a successful request with the requested Web page to follow. Another familiar response code is 404, meaning the requested document does not exist.
What Fabio spotted was response code 204 – the "No Content" response. This response says to the browser, "I've done what you asked, but don't have a new page for you to display." As it turns out, this is precisely how the no-refresh links on www.mp3.com and www.milehighcomics.com work!
Although any server-side scripting language may be used to generate a 204 No Content response, let's begin with a PHP example. The following will be our link that literally does nothing:
<a href="204.php">Click me!</a>
Similarly, the following will be a form that, when submitted, causes no visible change to the page:
<form action="204.php" method="POST">
This is just a normal HTML link and an ordinary HTML form; the magic is in 204.php, the script that these two HTML elements call:
<? header("HTTP/1.0 204 No Content"); ?>
This single line of PHP returns the 204 No Content response discussed above. If your Web server is equipped with PHP, try it yourself! If your server spits out a 500 error (internal server error), chances are good that you are running an Apache server with the CGI version of PHP, rather than the (quicker and more powerful) Apache module. In such configurations, you must instead use the following alternate syntax:
<? header("Status: 204 No Content"); ?>
Whichever code you end up using, when you click on the link your browser should do absolutely nothing. Depending on the specific browser and Web server you use, however, the little animation that indicates your browser is loading a page may start up. This is an unfortunate side effect of this method, which makes the inclusion of appropriate feedback all the more important. The following variations of the link and form, for example, will notify the user that the action has been taken:
<a href="204.php" onClick="alert('Done!');">Click me!</a>
<form action="204.php" method="POST" onSubmit="alert('Done!');">
In this case, the feedback isn't all that important; however, if we were to expand 204.php to do something interesting, like updating a counter in a MySQL database, we would then definitely want to let the user know that something had happened.
<?
$ok = mysql_query("UPDATE Counters SET Hits = Hits + 1 WHERE ID=42")
or die("A database error has occurred. Please try again.");
header("HTTP/1.0 204 No Content");
?>
Note that the above script may or may not generate a page in response to the user’s action. If the query occurs normally, then the 204 No Content response will be sent and no HTML document will be returned to the browser (again, use the alternate form given above if you are using the CGI version of PHP on Apache server). If the query fails for some reason, the call to die() returns a page with an error message to the browser, and the call to header() never happens (since die() terminates the script when it is finished).
More complex schemes can be used to determine whether or not to send a new page to the browser (depending on the value of a variable or the coordinates of a mouse click, for example), and applications for this ability can be imagined in areas such as simple online games.
For the ASP aficionados in the audience, the following script (written in VBScript) is the equivalent of the PHP example above. It will return nothing to the browser, and you are free to make the script do whatever you please by adding to it the required commands.
<% Response.Status = "204 No Content" %>
And here's how to do it in Perl using CGI.pm:
print header(-status=>'204 No Response');
I should mention one note of caution. In all of the above versions of this little trick, and likely in other scripting languages as well, the command that sends the 204 No Content response must not be preceded by any output to the page. In PHP, for instance, if your script were structured as follows, it would fail with an error:
<HTML>
<HEAD><TITLE></TITLE></HEAD>
<BODY>
<?
if (some condition) {
header("HTTP/1.0 204 No Content");
exit();
}
?>
...
The problem here is the HTML tags that appear before the PHP code. Your script can't decide not to send the browser a Web page when it has already begun transmitting that page to the browser.
Other than that, this technique is fairly straightforward. It just goes to show how we can take a technology for granted. Many of the readers of the Tech Times and I have built our careers working with the Web, and yet the very protocol upon which the Web is based is largely ignored -- or maybe HTTP just isn't as sexy as CSS and JavaScript.
If you're interested in reading more about the HTTP standard, your best bet is to go straight to the source: RFC 2616: The HTTP 1.1 Standard.