Published: Saturday, December 30, 2000
Creating "Quick-Links" Using a Custom 404 Page
By Johan Alveborg
The other day one of the marketing guys came around and asked if we
couldn’t fix up some easy-to-type URL’s for some pages on the site.
The site uses frames and the page requested should of course show up
in the main content frame in the same way as if the user had chosen it
from the menu. Until now, we had solved this with a parameter to the
frame-definition page, such as SomePage.asp?Page=42, and
then checking the Page-param in a Select Case
statement for the correct page to display.
Now, the marketing departement had dreamed up about 35 new direct-links
they wanted implemented, and they were of the opinion that
http://www.foo.com/somepage?page=42 didn’t really look
very good in print ads, and I had to agree :-)
The two most obvious ways to solve this were:
1.) Add 35 new virtual roots to our 25 IIS boxes, or
2.) Add 35 new directories in the webroot, each with a default page
that does a Response.Redirect to SomePage.asp
with the correct parameter.
On of our hired hands started off along the lines of option #2, but
I started thinking there hade to be a better way, and fortunately there
is! What happens if you request http://www.foo.com/bar and
the directory doesn’t exist? You get a "404 Page not found"-message.
Hrmmm, let's check... yes you can configure what page IIS serves when
the requested file or directory doesn’t exist, but it doesn’t seem to run
the ASP-code put in the page. What eluded me at first was that in the
IIS MMC you can set what type of page IIS should use for the error
messages, the default is "File" which just shoots the page to the user
without any processing. Changing the type to "URL" does the trick and
any ASP code in the page is now processed. IIS sends the URL the user
requested in the query string so it’s available to our ASP code to
check.
| For More Information on Custom 404 Error Pages |
|
To learn more about creating custom 404 error pages be sure to read
Creating a Custom 404 Error Page.
It is a very good and thorough article explaining how to setup such a
custom 404 error page! Another very worthwhile read on the subject
is Nathan Pond's Tracking 404 Errors.
|
So, the rest is pretty straightforward: In the ASP page IIS serves
when it can’t find a requested folder or file, check what folder the
user requests and if it’s one that you have anticipated, you redirect the
user to the correct page – in our case the frame definition page
with a parameter indicating what page to display in the main content
frame.
Begin by creating a 404.asp page and configure IIS to
serve that page for the 404 error code (don’t forget to set "Type" to
"URL"; for more information on setting up IIS properly and creating
such a custom 404 error page, be sure to read Creating a Custom 404 Error Page!)
In 404.asp, snarf out the directory the user has tried to
access using the following code:
SomeDir = Request.ServerVariables("Query_String")
SomeDir = UCase(Mid(SomeDir, InStrRev(SomeDir, "/") + 1, Len(SomeDir)))
'SomeDir now contains whatever the user typed after the last
'slash in the URL, if he typed http://www.foo.com/books SomeDir
'will contain "BOOKS".
|
and then use a Select Case to check and redirect as needed:
Select Case SomeDir
Case "BOOKS"
Response.Redirect("/SomePage.asp?Page=25")
Case "FOO"
Response.Redirect("/SomePage.asp?Page=42")
Case Else
Response.Write("The page you requested doesn’t exist...")
End Select
|
You could of course tidy things up by using an array of names/numbers
(in the format BOOKS;25) stored in an application variable
and loop through it. This would allow for an easy web-based updating
mechanism for adding new pages without having to change the
404.asp page. To accomplish this, in Global.asa
(or an admin page) set the array up as:
Dim RedirPages(2)
RedirPages(1) = "BOOKS;25"
RedirPages(2) = "FOO;42"
Application("404RedirectionPagesArray") = RedirPages
|
And in the 404.asp page:
RedirPages = Application("404RedirectionPagesArray")
'Put it in a local var to save typing later on
For I = 0 To UBound(RedirPages) – 1
If (Split(RedirPages(I), ";")(0) = SomeDir) Then
Response.Redirect("/SomePage.asp?Page=" & _
Split(RedirPages(I), ";")(1))
Response.End
End If
Next
|
Don't use the dictionary object (which otherwise would have been the
perfect method) since it's not thread safe. The
LookupTable object looks good but I haven’t tried it yet.
One of the coolest things about this hack is that it's very easy to
handle user requests for misspelled URL's: In the above example, just
add BOKS and BOOK to the array and you'll
at least have increased the chances that the user will get to the
page that they intended!
Happy Programming!
By Johan Alveborg