start blog post

AJAX Phrasebook

  1. Creating an AJAX object (XMLHttpRequest)
  2. Setting up a callback function
  3. Making GET requests
  4. Setting HTTP request headers
  5. POSTing form data
  6. Aborting an AJAX request in progress
  7. Server-side AJAX processing with PHP
  8. Serving XML, JSON, (X)HTML, or plain text
  9. Putting it all together: A reusable AJAX Singleton

Creating an AJAX object (XMLHttpRequest)

    // reusable XMLHttpRequest object
    var http = function() {
        return ('XMLHttpRequest' in window)
            ? new XMLHttpRequest()
            : (('ActiveXObject' in window)
                ? new ActiveXObject("Msxml2.XMLHTTP")
                : null);
    }();
top

Setting up a callback function

    // IE requires that you use http.open BEFORE assigning this
    http.onreadystatechange = function() {
        if (http.readyState === 4) {   // XMLHttpRequest code for "Done"
            if (http.status === 200) { // HTTP status code for "OK"
                // use http.responseText or http.responseXML here
            }
        }
    };
top

Making GET requests

    // simple GET request
    http.open("GET", "myPage.php", true); // false for synchronous (blocking)
    http.send(null);                      // null is required here
    
    // passing variables to PHP by modifying the URL
    var name = escape("Your Name");
    var age = 27;
    var queryString = "?name=" + name + "&age=" + age;
    http.open("GET", "myPage.php" + queryString, true);
    http.send(null);
top

Setting HTTP request headers

    http.open("GET", "myPage.php", true);
    
    /**
     * Set headers after open() and before send().
     * For a complete list of request headers, see:
     * http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html
     */
    http.setRequestHeader("User-Agent", "arguments.callee Custom UA");
    http.setRequestHeader("Accept", "text/plain, text/html, text/xml");
        
    http.send(null);
top

POSTing form data

    // gather form data
    var name = escape(document.getElementById("form-name").value);
    var address = escape(document.getElementById("form-address").value);
    
    // build query string
    var query = "?name=" + name + "&address=" + address;
    
    // make AJAX request
    http.open("POST", "myPage.php", true);
    http.onreadystatechange = function() {};
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-length", query.length);
    http.setRequestHeader("Connection", "close");
    http.send(query); // not "null" as with GET requests
top

Aborting an AJAX request in progress

    http.abort(); // it's that easy!
top

Server-side AJAX processing with PHP

<?php
    // gather POST (or GET) variables
    foreach($_POST as $key => $value) {
        $$key = $value; // note the double $$
        /**
         * Using the last POST example, this loop will
         * create the variables $name and $address.
         */
    }
    
    /**
     * ALWAYS sanitize user input immediately before using it.
     * htmlspecialchars() for displaying on a webpage
     * mysql_real_escape_string() when using a MySQL database
     * filter_var() for more customizable sanitization
     */
    echo htmlspecialchars("$name lives at $address!");
    exit;
?>
top

Serving XML, JSON, (X)HTML, or plain text

<?php
    header("Content-Type: text/xml; charset=utf-8");
    echo '<?xml version="1.0" encoding="utf-8"?>
        <root>
            <name>HB</name>
            <address>123 Any St.</address>
        <root>
    ';
    exit;
?>
<?php
    // some older browsers don't recognize JSON, so serve plain text to them
    $mime = preg_match("/application\/json/i", $_SERVER["HTTP_ACCEPT"]) ? "application/json" : "text/plain";
    header("Content-Type: $mime; charset=utf-8");
    echo '[{"name":"HB","address":"123 Any St."}]';
    exit;
?>
<?php
    header("Content-Type: text/html; charset=utf-8");
    
    /**
     * JavaScript may do something like this with the following response:
     * document.getElementById("targetDiv").innerHTML = http.responseText;
     */
    echo '<p>This paragraph was retrieved via AJAX!</p>';
    exit;
?>
<?php
    header("Content-Type: text/plain"); // useful for delimited data (CSV, etc.)
    echo "1, HB Stone, 123 Any St.\n";
    echo "2, Sample Name, 345 Another St.\n";
    exit;
?>
top

Putting it all together: A reusable AJAX Singleton

    var Http = function() {
        var ReadyStates = {
            UNINITIALIZED : 0,
            OPEN          : 1,
            SENT          : 2,
            RECEIVING     : 3,
            DONE          : 4
        };
        var Status = {
            OK           : 200,
            MULTIPLE     : 300,
            FORBIDDEN    : 403,
            NOT_FOUND    : 404,
            SERVER_ERROR : 500
        };
        var http = function() {
            return ('XMLHttpRequest' in window)
                ? new XMLHttpRequest()
                : (('ActiveXObject' in window)
                    ? new ActiveXObject("Msxml2.XMLHTTP")
                    : null);
        }();
        return {
            isBusy: function() {
                return ((http.readyState !== ReadyStates.UNINITIALIZED) && (http.readyState !== ReadyStates.DONE));
            },
            request: function(obj) {
                if (typeof obj.url !== "string") {
                    return;
                }
                var orsc function() { // onreadystatechange
                    if (http.readyState === ReadyStates.DONE) {
                        switch(http.status) {
                            case Status.OK:
                                if (typeof obj.success == "function") {
                                    obj.success.call(http, http, obj);
                                }
                                break;
                            // handle other cases here as desired
                            default:
                                if (typeof obj.failure == "function") {
                                    obj.failure.call(http, http, obj);
                                }
                        }
                    }
                };
                var query = function() {
                    if (typeof obj.data !== "object") {
                        return "";
                    }
                    var q = "";
                    for (var i in obj.data) {
                        if (obj.data.hasOwnProperty(i)) {
                            q += (q.length) ? "&" : "";
                            q += encodeURIComponent(i) + "=" + encodeURIComponent(obj.data[i]);
                        }
                    }
                    return q;
                }();
                switch(obj.method) {
                    // implement other methods as desired (HEAD, PUT, DELETE, etc.)
                    case "GET":
                        http.open(obj.method, obj.url + "?" + query, true);
                        http.onreadystatechange = orsc;
                        http.send(null);
                        break;
                    case "POST":
                        http.open(obj.method, obj.url, true);
                        http.onreadystatechange = orsc;
                        http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                        http.setRequestHeader("Content-length", query.length);
                        http.setRequestHeader("Connection", "close");
                        http.send(query);
                        break;
                    default:
                        return; // invalid or unsupported method
                }
            }
        };
    }();

Any time you want to perform a request, you can do something like this:

    Http.request({
        url: "weather.php",
        method: "GET",
        data: {
            zipCode = "92261"
        },
        success: function(http) {
            alert("Weather report: " + http.responseText);
        },
        failure: function(http) {
            alert("AJAX call failed! Status code: " + http.status);
        }
    });

var tags = [, , ];

  • share this post:
  • email a friend
  • float this post
  • digg this post
  • share on stumbleupon
  • submit to technorati
  • tweet this post

end blog post

most viewed this week

least viewed this week