smart 404
default server error pages do a decent job of letting whoever receives it know that what they expected to see doesn't exist. they're usually completely useless. but, using some fairly simple logic you can give your visitor a more helpful message
what causes 404 errors?
a 404 error means that the page requested doesn't exist. there are 3 things that can cause this to happen:
- the visitor typed the address in and misspelled it, or used an outdated bookmark
- there's a bad link on your own site that points to a page that doesn't exist
- there's a bad link out there on the web, another misspelling by someone trying to link to you, or perhaps you moved things and broke old links (don't do that, eh)
how we can handle these
using a couple of server variables it's possible to detect which of these three caused the error. we'll use the HTTP_REFERER header, sent to the site from the visitor's browser, to find out where they came from, combined with the SERVER_NAME variable to figure it all out:
- if HTTP_REFERER is blank, it means they aren't coming from another page somewhere; they either typed in the address or used a bookmark
- if a certain part of HTTP_REFERER (the part between http:// and the first /) matches the SERVER_NAME variable, it means they came from another page on the same site, and you have a bad link on that page.
- otherwise, there's a bad link somewhere out on the web. you could make your 404 script log that site somewhere so you could try contacting the site owner to get it fixed. or you could set up a redirect to the correct location.
where do these variables come from?
depending on what server setup you're on, you access these variables in different ways. in PHP you'll access the $_SERVER automatic variable like so:
$server_name = $_SERVER['SERVER_NAME']; $referer = $_SERVER['HTTP_REFERER'];
then you can carry out some simple comparisons to figure out exactly what happened:
if (preg_match("/http:\/\/".$server_name."/", $referer) ...
display a different message, depending on which conditions match, and there you have it, a more helpful error page!
not using php?
me neither. django apparently supports custom 404 error pages, but translating the basic idea from my original php implementation seemed easier. plus that way i could use the exact same, simple template i use for every other page on my site to display it.
getting the variables into a Context object was easy enough. they're stored in the request.META dictionary, so passing that to a 404 mini-template and using django's template syntax (plus a custom tag for the regex processing) gave me back the content I wanted to put into my normal default template, complete with the correct "error message". beauty! :)