There appears to be a flaw in the way that Microsoft's IIS works with the Response.Redirect
method. Well… Having had a chat with David Wang about it I can understand why it's done like it is, but that doesn't help those of us who like to do things properly/differently¹ [1Delete as applicable.].
If you look on-line all the examples seen will be in this sort of form:
<% Response.Redirect( "http://www.kirit.com/" ); %>
This works well for most sorts of redirects, but what happens when you have a URI with a space in it? All seems well if you do this:
<% Response.Redirect( "http://www.kirit.com/Response.Redirect and encoded URIs" ); %>
But if you have already correctly encoded the URL then it breaks:
<% Response.Redirect( "http://www.kirit.com/Response.Redirect%20and%20encoded URIs" ); %>
This is because the Response.Redirect takes what may be called a speculative approach to deciding how to encode the URL that you provide to it. This helps most ASP programmers to get the correct behaviour but means that the code is not compatible with, for example, redirecting back to a HTTP referrer² [2HTTP_REFERER
—it is spelled incorrectly in the standard.] because this is already encoded. Thankfully it is pretty easy to fix.
If you take a read through the HTTP standard (and you shouldn't be doing any web development without doing so) you will notice that there are many ways of doing redirects. Each one means something slightly different and they are used in different circumstances. Here is a recap of the ones you're likely to want to use:
You need to set one of these numbers in the Response.Status
field (for a normal page this would be 200 meaning OK). You also need to write a Location
header and depending on the method used in the request you should also include a short message body.
There are three methods that are important to redirects, GET, POST and HEAD. If the user agent has sent a HEAD request then you do not need to send a message body, and indeed you shouldn't send one.
A minimal body for a redirect that you expect to generate in response to a GET is outlined below:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head><title>Redirection</title></head> <body> <h1>Page moved<h1> <p>The page you want <a href="newURL.html">has been moved<></p> <body><html>
If the redirect is due to a POST from the user agent then you should use a message body like this:
<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head><title>Redirection</title></head> <body> <h1>Page moved</h1> <p>The page you want has been moved</p> <form action="newURL.asp" method="POST"> <p><input type="Submit" value="Go There" id="submit"></p> </form> </body></html>
Don't forget that if you're doing this you will need to add any parameters in as input hiddens and you will probably also want to change the button text and id to match what the resulting script expects.
Never use a HTTP refresh meta tag on this page (or on any other page); read the W3C's page on performing redirects; don't irritate your users!
It's always helpful to have a bit of code. This is the redirect function that is called after a forum post has been written to the database:
function Redirect( url ) { Response.Status = "303 See Other"; Response.AddHeader( "Location", url ); Response.Clear(); Response.Write( '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ' + '"http://www.w3.org/TR/html4/strict.dtd">\n' + '<html><head><title>Redirection</title></head>' + '<body><h1>Page moved</h1>' + '<p>The page you want <a href="' + url + '">has been moved</a>' + '</p></body></html>' ); Response.End(); }
Remember that the URL must be correct for this to work. No shirking by being sloppy when you do the encoding!