XMLHttpRequest 的標準化


實際上,早期 XMLHttpRequest 並非標準介面,就歷史上來說,非同步物件的概念,始於 Microsoft 為了 Exchange Server 建立的 Outlook Web Access 概念,後來被定義為 IXMLHTTPRequest 介面,並在 MSXML 程式庫的第二版中實現,1999 年的 Internet Explorer 5.0 搭載了該程式庫,可透過 ActiveX,使用 XMLHTTP 作為包裹器來存取。

Mozilla 後來在它們的 Gecko 樣版引擎中仿造了類似的介面 nsIXMLHttpRequest,行為上盡可能類似 IXMLHTTPRequest 介面,而後 Mozilla 建立了 XMLHttpRequest 物件作為包裹器以使用該介面,在 2002 年 Gecko 1.0 中 XMLHttpRequest 獲得了完整的實現,而在 Internet Explorer 之外的其他主流瀏覽器上,XMLHttpRequest 成了產業標準,而 Internet Explorer 要到 2006 年的 7.0 之後才有 XMLHttpRequest

後來 W3C 在 2006 年開始著手進行 XMLHttpRequest 的標準化,目標是在當時的實現中,取得可互通的最小集合,進一步地,在 2008 年發佈了曾經被稱為 XMLHttpRequest 2 或 XMLHttpRequest Level 2 的草案,其中包含了 XMLHttpRequest 的一些擴充功能,例如在事件上,增加了 onload 之類的處理器,以上例來說,可以使用 onload 改寫為:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
</head>
<body>

    <button id='req'>取得表格</button>
    <div id="table"></div>

<script type="text/javascript">

    document.getElementById('req').onclick = function() {
        let request = new XMLHttpRequest();
        request.onload = function(evt) {
            let req = evt.target;
            if(req.status === 200) {
                document.getElementById('table').innerHTML = req.responseText;
            }
        };
        request.open('GET', 'XMLHttpRequest-1.txt');
        request.send(null);
    };

</script>

</body>
</html>

按我觀看執行結果

onload 方法相當於 readyStateXMLHttpRequest.DONE,然而,事件處理器的第一個參數會是 ProgressEvent,它繼承自 Event,可以透過 lengthComputable 獲知可否評算回應的長度,total 取得回應的長度,loaded 取得目前已載入的長度,可搭配 onprogress 來實現進度顯示。

除了 onloadonprogress 事件處理器之外,還有 onloadstartonabortonerrorontimeoutonloadend 等處理器,事件發生時,處理器的第一個參數都是 ProgressEvent,而 XMLHttpRequesttimeout 屬性也是該規格定義之一。

如果回應是二進位資料,新的 XMLHttpRequest 可以直接透過 responseType 直接取得,新的 XMLHttpRequest 也可以處理檔案上傳,甚至透過 onprogress 來瞭解進度等。

新的 XMLHttpRequest 也支援 Cross-origin resource sharing(CORS),也就是可實現跨網域請求,只要伺服端支援 CORS 協議,XMLHttpRequest 在跨域請求時的方式並不用有特別的改變。

其他新功能還有,定義了 FormData 支援上傳檔案,若必須得知上傳進度,可以藉由 XMLHttpRequestupload 取得 XMLHttpRequestUpload 物件,透過註冊其 onprogress 來實現等。

在 2011 年時,新版的 XMLHttpRequest 草案規範被納入了原本的 XMLHttpRequest 規範中,成為了 XMLHttpRequest Level 1 規範的內容,而曾經的 XMLHttpRequest Level 2 就被廢棄了。

目前來說,想要取得 XMLHttpRequest 的規範,可以在〈XMLHttpRequest Level 1〉這個入口頁面找到,而現行規格的內容,可以在〈XMLHttpRequest Living Specification〉查看。

有些瀏覽器中,令 XMLHttpRequest 物件在事件註冊時,可以使用 addEventListener 之類的方法,不過,那並不在〈XMLHttpRequest Living Specification〉的規範之中。