Redirection Refresher Course

Suppose for the sake of argument that a URI on your site changes. I know, it happens so infrequently as to be unremarkable, but suppose it does. How do you handle it?

A common means of programmatically sending visitors to the new URI is the “meta refresh.” For example,

<meta http-equiv="Refresh" content="20; URL=http://my.example.com/" >

Using this method within an HTML document gives the impression of usability, because it allows the author to notify the visitor that something has changed. Except this method breaks the back button and is incompatible with some HTTP user agents, particularly those who don’t have humans sitting in front of them.

It is better than nothing, but don’t use it if you have a better alternative.

A similar method uses a scripting language, such as JavaScript, to set the page location to a new value.

<script type="text/javascript" language="javascript">
window.location = "http://my.example.com/";
</script>

or

<script type="text/vbscript" language="vbscript">
window.navigate "http://my.example.com/"
</script>

This method, in some user agents, does not break the back button. In others it does. When it does break the chain of events, it does so in a way that dramatically interferes with the user experience: it causes a loop. Again, this method is incompatible with HTTP user agents which do not interpret the specific scripting language.

Don’t use it either.

What you’re really looking for is a particular HTTP status code, either 301 Moved Permanently, 302 Found, or 307 Moved Temporarily. (There are other redirection codes, but those are the most common.)

There are two questions that are raised when HTTP status codes are suggested. Both are valid concerns. The first is, how do we notify the end user that the URI has changed, so that the user may update his bookmarks?* This is simple: Notify the visitor at the destination. The second is, how do we send a header when we have no control of the web server?

Who said you have no control of the web server? If you are restricted to using only HTML, CSS, and client-side Javascript, then this may be so, but many of us here use web servers which will happily execute any of a number of server-side languages.

In Cold Fusion, you would do

<cfheader statusCode="301" statusText="Moved Permanently">
<cfheader name="Location" value="http://my.example.com/">
<cfcontent type="text/html; charset=utf-8" file="AnExplanation.html">

We include the file AnExplanation.html because some user agents may not follow redirects, or the method used may prohibit automatically following the redirect. As the specification states,

Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

Note that some Cold Fusion installations prohibit execution of the cfoutput element. In that case, you would need to include the explanatory HTML following the cfheader element in your CFML document. Take a look at our example.

But perhaps you’re using Active Server Pages (ASP) instead of Cold Fusion. In that case, you’ll want to use the Response object to set the appropriate headers. The Response.Redirect method only emits a 302 Found redirect. To gain control over the actual status used, use the Response.Status property in conjunction with the Response.AddHeader method, as you can see in our example.

Or, for PHP, look at our example in action or in source.


* I think this is a user agent failure. The user agent should keep the bookmarks up-to-date.