This page has been archived. For the latest news on FormAssembly, go to: http://www3.formassembly.com/blog

Treating the HTTP Status code right

If you’ve been following the whole Ajax thing for a while, you’ve certainly seen this few lines of code hundreds of times. You know, the ones that check the readyState and status properties of a xmlHttpRequest.

    if (req.readyState == 4) {
        if (req.status == 200) {
            // ...processing...
        } else {
            alert("There was a problem retrieving the XML data:n");
        }
    }

The status is the HTTP code returned by the web server (here 200, meaning that everything went fine). Normally, the status code is part of the private conversation between the browser and the web server. You don’t have to worry about it, unless of course you encounter the dreaded 404 Page Not Found.

Things change when you start developing Ajax-style with XmlHttpRequest. You are basically by-passing the browser native handling of HTTP and left dealing with the status code on your own. And, that’s a great opportunity. Why ? Because you can
use it to relay information about the execution of your server-side scripts.

The HTTP protocol defines many status codes. For a web developer some of the interesting ones are:

  • 200 Ok
  • 201 created
  • 400 bad request
  • 403 forbidden
  • 500 internal server error

Most server-side scripting languages will let you modify the http response header and set just about any status code. For instance in PHP, if you were processing a request that looked suspicious (a tempered query string?) you could do:

< ?php
header('HTTP/1.0 400 Bad Request');
die('sorry, the execution failed for some reason..');
?>

If you are processing a login/registration form, you could use header('HTTP/1.0 200 Ok') for a successful login, header('HTTP/1.0 201 Created') if a registration was ok and an account was created, and maybe header('HTTP/1.0 403 Forbidden') for a wrong password or if the username was already taken.

Back to the javascript code, here’s now a smarter response handler for the authentication example.

switch (req.status) {
    case 200:
            // login ok, moving on...
            break;
    case 201:
            // was a registration.. will show a welcome message.
           showWelcomeMessage(req.reponseText);
           break;
    case 403:
           // authentication problem. The error message is in responseText
          showErrorMessage(req.responseText);
          break;
    default:
         // unknown error
         alert("There was a problem..");
    }

Remark: Safari will return a ‘undefined’ status code if the response content is empty, so make sure to have at least a space in the response (using echo "" in PHP for instance).

That’s it! Happy coding in 2006.

7 Responses to “Treating the HTTP Status code right”

  1. Ajaxian » Using the error codes from XHR calls Says:

    […] Over at The Form Assembly they are discussing Treating the HTTP Status code right. […]

  2. Anne van Kesteren Says:

    How about 301 and 302? Are they handled by the browser or do you have to do subsequent requests yourself? (I still have to test this all one day.)

  3. cedsav Says:

    You have pretty much to handle everything yourself. 301 and 302 don’t trigger a redirection and 401 does not prompt the browser’s login window.

    There are some inconsistency accross browsers though. See: http://www.formassembly.com/test/teststatus.html

    It looks like the 400s error message are more reliable. I’ll add the 200s and 500s to the test soon.

  4. cedsav Says:

    btw, I fixed the PHP code sample in the post (was missing the HTTP/1.0 part in the header).

  5. Xia Says:

    Thanks for that safari tip! I was getting undefined errors when I did getAllResponseHeaders, but by echoing ‘ ‘ this problem is solved!

    Thanks :)

  6. AjaxDude Says:

    Very nice. The Safari clue was great. Had a problem with undefined status in Safari, one Google and two clicks later I found this page. Thanks. :-)

  7. Koas Says:

    Once again thanks for the tip on Safari, I had headaches for half an hour before I googled it and found your post!