跳到主要內容

Ajax 基礎使用

last updated:2013/04

最早期的網路資料處理做法必須等待頁面回應後,才能進行下一步動作
等待頁面回應的過程中不能進行任何事,所以非常沒效率
所以後來發展出Ajax技術提高資料處理的效率

Ajax名稱的由來是 Asynchronous JavaScript + XML
在早期通常都將需要進行動態變更的資料儲存在XML檔中
能在不影響目前用戶體驗的前提下,由JavaScript在背後發送請求訊息更新資料
即使現在大多以更省傳輸量的JSON傳遞資料,這項異步(非同步)技術還是被叫做Ajax
GitHub檔案目錄

JavaScript內建一個XMLHttpRequest物件
用於初始Ajax請求,並處理Ajax回應
它有比較複雜的類別成員及方法:
abort() -
取消Ajax請求

open() -
準備請求,指定請求的型態、URL與其他細節

send() -
傳送請求給伺服器

readyState -
請求的狀態碼代號;0表示未初始,1是開啟,2是已傳送,3是接收中,4是已載入

status -
HTTP的請求狀態代碼(ex:404錯誤,200表示正常)

onreadystatechange -
請求狀態改變時會被呼叫的參考
                              
responseText -
伺服器回傳的純文字字串資料

responseXML -
伺服器回傳的的XML資料


因為不同的瀏覽器(簡單來說就是IE...)有不同的 XMLHttpRequest 物件建立方式
包裝一支函式來處理取得XMLHttpRequest 物件:

function getHTTPObject() {
    var xmlhttp = false;
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
        // for old IE version
    } else if (window.ActiveXObject) {
        try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return xmlhttp;
}

var request = getHTTPObject();  //build  XMLHttpRequest object

建立Ajax請求物件後,接著要設定伺服器傳回資料後的處理方式,之後再開啟請求
API 如下:
request.onreadystatechange = handler;       //if onreadystatechange is triggered, set function to handle
request.open(type, url, true);                          //true set for being always asynchronous

open() 的第一個參數是 HTTP request 的方法
也就是從 GET、POST、HEAD 等伺服器支援的方法中依需求使用
HTTP 標準規定這些方法都是大寫表示
盡量遵守這規則以避免有的瀏覽器不支援
第二個參數是請求頁面的 URL
基於安全考量,呼叫同網域以外的網頁是被禁止的
如果網域不同,則叫用 open() 時會出現「權限不足,拒絕存取」那類的錯誤
詳細可見跨網域資料取得解決方式 - JSONP
第三個參數決定此 request 是否不同步進行,true表示採用同步,false則表示異步
所謂的同步就是像 alert()、confirm()之類的方法會強制執行完後才繼續執行其餘的程式
實務上,大部分場合採用異步會是較好的做法

type一般選擇填入 "GET" 或 "POST"
GET 適用於不會改變伺服器任何設定的資料傳輸
有需要的話還能透過 url 傳小量資料到伺服器
範例:
request.open("GET", "a.jsp?param1=true", true);
request.send(null);                                    //send nothing

POST 適用於會變更伺服器設定的資料傳輸
有個說法是POST傳輸過程會多送一些封包而降低效率,所以盡量用GET傳輸
但實際上僅有在IE才會有這種現象
而且基於安全性考量,該用POST的時候就用POST
範例:
request.open("POST", "addData.php", true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;
                                                 charset=UTF-8"); 
request.send("date=10/10/18&demo_string=Hello World!");     //send query string

以 POST 方式傳送資料前,必須先設定好 Content-Type 為表單格式
application/x-www-form-urlencoded; charset=UTF-8 表示資料的型別是 URL-encoding
而資料則以查詢字串的方式列出

以下再分別針對 Get 和 Post 包裝出函式以利重複使用

function ajaxGet(callback, url, sync) {
    var _reader = getHTTPObject();

    _reader.open('GET', url, !sync);
    if (!sync) {
        _reader.onreadystatechange = function () {
            if (_reader.readyState == 4) {
                if (_reader.status != 200) {
                    return false;
                }
                if (callback) callback(_reader);
            }
        };
    } else {
        if (_reader.status != 200) {
            return false;
        }
        if (callback) callback(_reader);
    }
    _reader.send(null);

    return true;
}

function ajaxPost(callback, url, sync, postQueryString) {
    var _reader = getHTTPObject();

    _reader.open('POST', url, !sync);
  _reader.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    if (!sync) {
        _reader.onreadystatechange = function () {
            if (_reader.readyState == 4) {
                if (_reader.status != 200) {
                    return false;
                }
                if (callback) callback(_reader);
            }
        };
    } else {
        if (_reader.status != 200) {
            return false;
        }
        if (callback) callback(_reader);
    }
    _reader.send(postQueryString);

    return true;
}


以下示範使用實例:
//handler function execute response data from ajax query
function handler(res) {
    ... //do something with res.responseText
}

ajaxGet(handler, '/test.jsp?p=1',true);
ajaxPost(handler, '/test.jsp',true,'p1=1&p2=2');

留言