HTTP定義POST來發送資料給伺服器,POST適用於非等冪操作,POST有可能會改變伺服端的狀態,像是修改資料庫的內容,或在伺服器上儲存檔案等。
如果要發送POST,則可以在非同步物件open()時,將第一個參數設為'POST',之後使用setRequestHeader()設定內容類型,因為POST要發送的資料會放在請求的本體中,所以你必須告知發送的資料類型為何,接著在send()時,將要發送的資料,作為send()的引數傳入。
例如,若發送表單類型資料,必須設置請求標頭'Content-Type'為'application/x-www-form-urlencoded',以下是個示範:
...
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);
          
          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);
放在POST本體中的資料,也有可能是其它格式,例如XML或JSON,你必須設定不同的請求標頭,這在之後還會說明。
在下面這個例子中,將先前對非同步物件的基本操作進行了簡單的封裝,並使用POST來作 使用 GET 請求 中第二個範例。
<!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() {};
                    // 沒有 url,啥事也作不了
                    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 已存在';
                                    }
                                    document.getElementById('message')
                                        .innerHTML = message;
                                }
                            }
                        }
                    });
                };
            };
        </script>        
    </head>
    <body>
        新增書籤:<br>
        網址:<input id="url" type="text">
        <span id="message" style="color:red"></span><br>
        名稱:<input type="text">
    </body>
</html>
在上例中,呼叫ajax()時必須傳入選項物件,可使用的選項為:
- type指定請求類型,預設為'GET'
- url指定請求的URL
- data指定請求參數
- header指定請求標頭,預設'Content-Type'為'application/x-www-form-urlencoded'
- callback指定回呼函式,回呼函式的this與第一個參數會綁定為非同步物件(因為onreadystatechange設置的回呼函式中第一個參數,Firefox是傳入事件,Internet Explorer則無傳入任何東西,函式中的this,Firefox中是XMLHttpRequest,Internet Explorer中是window,因此這邊予以統一)
 

