最近在做一個關於Ajax的項目,項目本身非常簡單,但是接手項目之時,設計了過多的特效,導致為了兼容不得不讓代碼幾何增加。設計項目設計圖之時也過於簡單潦草,不過總算完成任務,但不能就此了之,必須得擠些時間出來回顧和總結,將好的一些經驗和不足之處分別進行記錄,避免同一個地方跌倒兩次。
進入正題,XMLHttpRequest對象其實是瀏覽器的一個標准接口,主要通過http協議與后台服務器交換數據,可惜地是這個接口一直沒有得到W3C的標准化,直到HTML5的概念出現。不過,2008年2月份,已經提出了XMLHttpRequest Level 2的草案。
創建XMLHttpRequest
通過XMLHttpRequest對象發送HTTP請求至少需要以下幾個步驟(當然還可以采取更多的其他步驟):
- 創建一個XMLHttpRequest對象,目前沒有跨瀏覽器的創建方法;
- 指定新創建的XHR對象打開一個特定的文件,也就是調用open()方法;
- 通知對象如何處理響應的數據,也就是注冊onreadystatechange事件處理程序;
- 讓對象發送請求,調用send()方法。
路要一步一步走,先創建一個XMLHttpRequest對象。在這里提供一個能兼容絕大部分現存瀏覽器的方法。
function createXHR(){ if(typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined") { var vers = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp.2.0"]; for (var i = 0, len = vers.length; i < len; i++) { try { var xhr = new ActiveXObject(vers[i]); return xhr; } catch (ex) { alert("Function createXHR error: " + ex.message);
continue; } } } else { throw new Error("No XHR object available."); } }
不能兼容的主要是IE,因為在早期的IE版本中,這個對象是一個ActiveX對象。"MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp.2.0",這些都是ActiveX對象名稱,具體用哪個取決於用戶的windows配置,而不是瀏覽器決定。里面使用了try/catch語句,如果創建成功,就返回此對象,若不存在的否則進入下一次循環繼續創建。
打開請求
下一步,打開一個新請求,這是為發送請求做准備,真正的發送指令是send()。
open()方法包含三個參數,第一個參數定義為請求的方式:GET、POST、PUT、HEAD等,前面兩個是最常用的,這些方式不區分大小寫,但是通常都以大寫形式出現,以匹配HTTP協議。GET是把數據作為查詢字符串追加在URL上,傳送給服務端,適用於常規請求,例如:URL完全指定了請求資源,或者請求對服務器沒有副作用以及服務器響應可緩存之時;POST是讓數據隨着HTTP請求的正文發送,也就是寫入body內,通常用於發送HTML表單信息,而且是非冪等的,也就是說相同的URL的重復POST請求從服務器端得到的響應可能不同,同時不應該緩存使用這個方法的請求。
var xhr = createXHR(); xhr.open(type, url, isAsy);
HEAD方式使用比較少見,此請求只返回響應的HTTP頭部,而非響應的主體,可以用來顯示文件的最后的修改日期。另外,使用POST方法時,必須記得設置請求的內容類型,這點經常容易忘記,這次有位組成員也犯了此錯誤,不過調試一下,很容易追蹤到這類的錯誤。(Content-Type: [type]/[subtype]; parameter)type常用的幾種形式Text、Application、Image、Message、Audio、Video等,subtype用於指定type的詳細形式,例如:
- text/plain(純文本)
- text/html(HTML文檔)
- application/xhtml+xml(XHTML文檔)
- image/gif(GIF圖像)
- image/jpeg(JPEG圖像)【PHP中為:image/pjpeg】
- image/png(PNG圖像)【PHP中為:image/x-png】
- video/mpeg(MPEG動畫)
- application/octet-stream(任意的二進制數據)
- application/pdf(PDF文檔)
- application/msword(Microsoft Word文件)
- multipart/alternative(HTML郵件的HTML形式和純文本形式,相同內容使用不同形式表示)
- application/x-www-form-urlencoded(使用HTTP的POST方法提交的表單)
- multipart/form-data(同上,但主要用於表單提交時伴隨文件上傳的場合)
url參數時訪問服務端數據的URI,疊加查詢字符串也需要用到,最后的isAys是通知瀏覽器是否需要異步的布爾值,true為異步,false為同步,缺省值為false。異步也即是說,在進行某些需要比較長時間的操作時,瀏覽器不必等到服務端的數據返回,而是立即執行后面的代碼,接觸過回調函數的TX很容易理解這點。反之,則需要無聊地等待。當然,絕大部分情況下,都是用true,要不然沒必要是用XHR。
注冊處理事件程序
接着,需要先注冊readystatechange事件處理程序,必須在open()方法之后,send()方法之前。事件處理程序也就是根據服務端返回的readystate進行判斷,是否可以進行響應的數據處理。readystatechange事件一共五個就緒的狀態,web開發者必須得將它們熟爛在肚子里。
| 數值 | 意義 | 詳細描述 |
| 0 | 未初始化(UNSENT) | 已經創建了XHR對象,但未調用open() |
| 1 | 加載中(OPENED) | 已經創建了XHR對象,但未調用send() |
| 2 | 已加載(HEADERS_RECEIVED) | 已調用send(),但是狀態和頭信息還不可以使用 |
| 3 | 交互中(LOADING) | 已經接受到了部分數據信息 |
| 4 | 完成(DONE) | 所有的數據接受完成,全部可以使用 |
就緒狀態4最為常見,意思為可以使用response對象的數據信息。
發送操作
緊接着,調用send()方法,send方法需要一個參數,若是POST方法,參數就是傳遞的數據,也就是body內容;若是GET方法,參數就是null。發送請求后,等待響應到達。(此處未考慮多個request異步並發)一旦到達,onreadystatechange事件處理程序就被激發,並按照指示執行事情。
時間關系,未完待續....(已經11:35)
