蹉跎到今天終於要寫Ajax部分了,平時工作中除了選擇器我用jQuery的最多的就是ajax,所以這部分在自己的框架中必不可少。
XMLHttpRequest
我以為對每個使用過Ajax的人來說XMLHttpRequest物件肯定是如雷貫耳,可是在和公司小夥伴兒的討論中我意識到,這個物件對有些已經使用Ajax很久的人來說仍然很陌生,jQuery等類庫把XMLHttpRequest物件封裝的太好了,以至於我們都不知道自己在使用它。關於JavaScript原生的Ajax之前寫過一篇Ajax初步理解的部落格,為了方便下面書寫,在這裡再介紹一下幾個重點概念。
Ajax的核心是JavaScript物件XmlHttpRequest,這個物件為向伺服器傳送請求和解析伺服器響應提供了流暢的介面。XmlHttpRequest可以使用JavaScript向伺服器提出請求並處理響應,而不阻塞使用者。該物件有兩個重要方法open與send
呼叫send()方法,請求被髮往伺服器,伺服器根據請求生成響應(Response),傳回給XHR物件,在收到響應後相應資料會填充到XHR物件的屬性,有四個相關屬性會被填充:
1. responseText:作為響應主體被返回的文字
2. responseXML:如果響應內容的型別是”text/xml”或”application/xml”,這個屬性將儲存包含著相應資料的XML文件
3. status:響應的HTTP狀態(200,404,500等)
4. statusText:HTTP狀態說明
XHR物件有一個readyState屬性,該屬性表示請求/響應過程中的當前活動階段,每當readyState值改變的時候都會觸發一次onreadystatechange事件。
瀏覽器相容的建立XHR物件方法
大家都懂得,IE總會製造些麻煩,看看瀏覽器相容的建立XHR物件方法,具體過程可以看看Ajax初步理解中的說明
function __createXHR(){ var xhr = null; try { // Firefox, Opera 8.0+, Safari,IE7+ xhr = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { xhr = null; } } } return xhr; }
封裝
其實看看第一段關於XHR物件的說明就明白為什麼jQuery等類庫會對XHR做如此徹底的封裝了,這個物件實在是太複雜了,引數的設定都要有時機問題,所以我也走上了封裝之路。
ajax: function(configs) { var settings = { "url": "", //請求地址 "method": "post", //請求使用方法 "user": "", //使用者名稱 "password": "", //密碼 "data": null, //引數(text/json) "responseType": "text", //返回值獲取方式 text/xml "headers": {}, //自定義的HttpHeader "enableCache":true, //是否使用快取 "onSucceed": null, //成功控制程式碼 "onClientError": null, //客戶端錯誤控制程式碼 "onServerError": null //伺服器端錯誤控制程式碼 }; for (s in settings) { settings[s] = configs[s] ? configs[s] : settings[s]; //應用自定義配置 } var xhr = _createXHR(); //建立XHR物件 xhr.onreadystatechange = function() { if (xhr.readyState == 4) { //請求完成,響應就緒 var result = settings["responseType"] == "text" ? xhr.responseText : xhr.responseXML; //返回值型別 if (((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) && typeof settings['onSucceed'] == 'function') { //成功 settings['onSucceed'](result, xhr.status); } else if (xhr.status >= 400 && xhr.status < 500) { //客戶端出錯,404啊神馬的 settings['onClientError'](result, xhr.status); } else if (xhr.status >= 500) { //伺服器端出錯 settings['onServerError'](result, xhr.status); } } } xhr.open(settings['method'], settings['url'], settings['user'], settings['password']); //傳送請求 if (typeof settings['headers'] == 'object') { //設定自定義headers var headers = settings['headers']; for (h in headers) { xhr.setRequestHeader(h, headers[h]); } } if(!settings['enableCache']){ //禁用快取 xhr.setRequestHeader("If-Modified-Since","0"); } if (settings["method"].toLowerCase() == "post") { //post請求 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); var data=""; if(typeof settings["data"]=='object') { for(d in settings["data"]){ data+=(d+'='+settings["data"][d]); } }else{ data=settings["data"]; } xhr.send(data); //傳遞引數 } else { xhr.send(); //get請求 } }
最後
這樣一個簡單的Ajax封裝就完成了,使用的時候和jQuery類似
ssLib.ajax({ "url": "testajax.php", "data":{"name":"Byron"}, "onSucceed": function(result) { alert(result); } });
看起類不錯,不過沒實際使用過呢還,希望大家多給意見。