《JavaScript高級程序設計》Chapter 12 Ajax與Comet
Chapter 21 Ajax與Cometphp
Ajax:Asynchronous JavaScript + XML
然而重點並不在於處理數據格式(不只限於處理XML),而是無需刷新或者卸載整個頁面就能夠向服務器請求格外的數據而且取得這個數據。(而後就能夠用DOM處理這些數據了)。
在沒有Ajax這個觀點提出來以前,其實已經可以實現。這個是個事實標準而已。
核心:XMLHttpRequest對象(XHR對象),將瀏覽器原生的通訊能力提供給開發人員。Ajax的流程基本圍繞着這個對象實現。
XMLHttpRequest對象
建立XMLHttpRequest對象跨域
IE5及以前版本(舊版本):XHR對象經過MSXML庫中的ActiveX對象實現,會遇到三個不一樣的版本:MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0。所以依考MSXML庫建立XMLHttpRequest對象,須要檢查檢查三個版本哪個可用,而後賦給arguments.callee.activeXString,進而經過new ActiveXObject(activeXString)建立。
IE7及更高版本、其餘瀏覽器:經過原生的XHR實現,即經過new XMLHttpRequest()建立
能夠按照上述狀況作一個簡單的能力檢測函數。
XHR的用法(通常流程)
建立XHR對象:方法同上。
調用open()方法,啓動一個請求以備發送(而不是真正發送了這個請求。傳入3個參數:發送請求的類型("get","post")、請求的URL、是否異步發送請求的布爾值。注意只能向「同一個域、同一個端口、同一個協議」的URL發送請求(若是須要跨域,看後面的跨域技術部分)。
調用send()方法,發送特定的請求:若是不須要傳輸數據,則仍要send(null)形式傳入null參數。
檢查響應狀態: a. 請求同步 的時候:JS會等服務器相應後再繼續執行,接到響應後,響應的數據會自動填充XHR對象的屬性(responseText/responseXML/status/statusText)。接到響應後,第一步是檢查status屬性(xhr.status>=200 && xhr.status<300)||xhr.status == 304. b.發送異步請求 的時候:檢測XHR對象的readyState屬性。只要readyState屬性值從一個變成另外一個,都會觸發一次readystatechange事件(通常考慮值爲4的狀況)。而通常在open()方法前
Abort()方法取消異步請求。且注意對XHR對象進行解除引用的操做。不建議重用XHR對象。
HTTP頭部信息(流程中還應該處理的)
處理HTTP請求或者響應的相應頭部信息。
能夠經過setRequestHeader()方法設置自定義的請求頭部信息。
而且建議這麼作,注意這個設置放在調用send()以前。
getResponseHeader()/getAllResponseHeaders()方法獲取相應的響應頭部信息。
服務器端能夠用頭部信息向瀏覽器發送數據。
GET請求
經常使用於向服務器查詢信息。
須要將這些信息附加到URL的末尾。
查詢字符串有嚴格的格式,須要通過encodeURIComponent()對每一個名和值進行處理,而後構造出特定的URL格式:例如:"example.php?name1=value1&name2=value2"
固然GET請求的初始化經過open()方法,這時的URL就是通過處理的URL了。
POST請求
向服務器發送應該被保存的數據。一般數據是請求的主體,且數據量大、格式不限。因此須要通過必要的處理。
服務器對POST請求和提交Web表單的請求不會一視同仁(而咱們須要它能統一處理),服務器通常會讀取發送過來的原始數據解析其中有用的部分。因此咱們能夠用XHR來模仿表單的提交: a. Content-Type頭部信息應該設置爲application/x-www-form-urlencoded b. 而後以適當的個數格式建立字符串,用serialize()對錶單進行序列化。 c. 最後以send()方法將上述經序列化處理的字符串發送。
顯然POST請求消耗的資源比GET的多、固然速度會慢。
XMLHttpRequest 2級
XMLHttpRequest 1級描述XHR對象實現的基本流程,XMLHttpRequest 2級進一步對其發展。
FormData
建立專門的FormData類型,以簡化上面提到過的POST請求的時候修改頭部信息、序列化表單的操做。
New FormData()建立相應的對象,傳入待發送的表單數據,最後調用send()方法將其發送便可。
主要是免去了處理頭部信息的步驟。
超時設定
timeout屬性:設置毫秒值。當通過這段時間沒有獲得相應則調用ontimeout事件處理程序。
overrideMimeType()方法
顧名思義,重寫服務器返回的MIME類型。
在send()被調用以前使用。
進度事件
6個進度事件
每一個請求都從觸發loadstart事件開始,接下來是一個或者多個progress事件,而後根據狀況觸發error/abort/load事件中的一個,最後以觸發loadend事件結束。
load事件:FireFox用以簡化異步交互的模型,代替readystatechange事件。然而瀏覽器只要收到服務器的響應,無論其狀態都會觸發load事件,因此仍然須要檢查status屬性。
progress事件:在接收數據期間週期性觸發,有三個額外的屬性:lengthComputable/position/totalSize,能夠用來建立進度指示器。 這個事件與onload事件、onreadystatechange事件處理程序同樣,須要在open()方法前添加。
跨域資源
用XHR試想Ajax通訊的主要限制:跨域安全限制。
CORS定義了當必須實現跨域訪問的時候,瀏覽器和服務器應該如何溝通。基本思想就是用自定義的HTTP頭部讓瀏覽器和服務器進行溝通,從而決定請求和響應是成功仍是失敗(判斷兩邊的對應參數是否匹配,有點像設備間的藍牙匹配)。
瀏覽器Origin頭部、服務器Access-Control-Allow-Origin頭部
簡單處理的狀況下,請求和響應都不包含cookie信息。
IE對CORS的實現:
XDR類型:相似XHR類型
它的open()方法只幾首兩個參數:請求類型和URL
只進行異步請求
其餘瀏覽器對CORS的實現
WebKit經過XMLHttpRequest對象實現了對CORS的原生支持
無需額外編寫代碼就能夠觸發這個行爲,只要在open()方法中傳入絕對URL便可。(也就是說會自動進行處理)
Preflighted Requests
帶憑據的請求(憑據:cookie、HTTP認證、客戶端SSL證實等。簡單跨域處理不帶)
其餘跨域技術
圖像Ping、JSONP、Comet(長輪詢、HTTP流)、Web Sockets
圖像Ping和JSONP是另外兩種跨域通訊的技術,但不如CORS穩妥。
Comet是對Ajax的進一步擴展,讓服務器幾乎可以實時地向客戶端推送數據。實際上重點在服務器向瀏覽器的推送。
Web Sockets是一種與服務器進行全雙工、雙向通訊的信道,不適用HTTP協議。
歡迎關注本站公眾號,獲取更多信息