Making POST Requests



HTTP defines POST as posting data to the Request-URI. POST is a non-idempotent method. That is, the side-effects of N > 0 identical POST requests may be different. POST may change the server's state, such as changing database content or store files on the server.

We can send a POST request by setting 'POST' to the first parameter of the asynchronous object's open function, and then use the setRequestHeader function to specify its content type. The posted data will be put in the post body of the request, so the server needs the content type information. The posted data will be the argument when calling the send function.
 
For example, when posting form data, the 'Content-Type' header should be 'application/x-www-form-urlencoded'. The following is a demonstration.
...
var url = 'somewhere';
var queryString = 'a=10&b=20';
xmlHttp.open('POST', url);
xmlHttp.setRequestHeader('Content-Type',  'application/x-www-form-urlencoded');
xmlHttp.send(queryString);

The data put in the post body may be other formats, such as XML or JSON. You should set respective request headers for them. I'll mention them afterword.

The following example encapsulates several operations of asynchronous objects, and use that to rewrite the second example of Making GET Requests.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN">
<html>
    <head>
        <meta content="text/html; charset=UTF-8" http-equiv="content-type">
        <script type="text/javascript">
            window.onload = function() {
                var xhr = window.XMLHttpRequest && 
                      (window.location.protocol !== 'file:' 
                          || !window.ActiveXObject) ?
                       function() {
                           return new XMLHttpRequest();
                       } :
                       function() {
                          try {
                             return new ActiveXObject('Microsoft.XMLHTTP');
                          } catch(e) {
                             throw new Error('XMLHttpRequest not supported');
                          }
                       };
                
                function param(obj) {
                    var pairs = [];
                    for(var name in obj) {
                        var pair = encodeURIComponent(name) + '=' + 
                                   encodeURIComponent(obj[name]);
                        pairs.push(pair.replace('/%20/g', '+'));
                    }
                    return pairs.join('&');
                }
                
                function ajax(option) {
                    option.type = option.type || 'GET';
                    option.header = option.header || {
                      'Content-Type':'application/x-www-form-urlencoded'};
                    option.callback = option.callback || function() {};
                    
                    if(!option.url) {
                        return;
                    }
                    
                    var request = xhr();
                    request.onreadystatechange = function() {
                        option.callback.call(request, request);
                    };
                    
                    var body = null;
                    var url = option.url;
                    if(option.data) {
                        if(option.type === 'POST') {
                            body = param(option.data);
                        }
                        else {
                            url = option.url + '?' + param(option.data) 
                                     + '&time=' + new Date().getTime();
                        }
                    }
                    
                    request.open(option.type, url);
                    for(var name in option.header) {
                        request.setRequestHeader(
                                name, option.header[name]);
                    }
                    request.send(body);
                }
                
                document.getElementById('url').onblur = function() {
                    ajax({
                        type: 'POST',
                        url : 'POST-1.php',
                        data: {url : document.getElementById('url').value},
                        callback: function(request) {
                            if(request.readyState === 4) {
                                if(request.status === 200) {
                                    var message = '';
                                    if(request.responseText 
                                         === 'urlExisted') {
                                        message = 'URL existed';
                                    }
                                    document.getElementById('message')
                                        .innerHTML = message;
                                }
                            }
                        }
                    });
                };
            };
        </script>        
    </head>
    <body>
        Add a bookmark<br>
        URL: <input id="url" type="text">
        <span id="message" style="color:red"></span><br>
        Title: <input type="text">
    </body>
</html>

In the above example, you can pass the ajax function an option object. The available options are as follows: 
  • type: Used to specify the request type. The default value is 'GET'.
  • url: The requested URL.
  • data: The request parameters.
  • header: The request header. The default value is 'application/x-www-form-urlencoded'.
  • callback: The callback function for different states of the asynchronous object. Its first parameter and this will be the asynchronous object. (The first parameter of the callback function referred by onreadystatechange is an event object in Firefox, but undefined in Internet Explorer. The callback function's this is the XMLHttpRequest instance in Firefox, but window (the global object) in Internet Explorer. We encapsulate these in-consistencies here.)