==ajax技術可以向服務器請求額外的數據而無需卸載頁面==。其核心技術是XMLHttpRequest對象(XHR)。
IE7以前的舊版本經過MSXML庫中的ActiveX對象實現。而IE7及以後的瀏覽器支持XMLHttpRequest構造函數
能夠作兼容性的createXHR();php
function createXHR(){ //檢查是否支持XMLHttpRequest if(typeof XMLHttpRequest!="undefined") { //支持,返回XMLHttpRequest對象 return new XMLHttpRequest(); } //若是不支持XMLHttpRequest,就檢查是否支持ActiveXObject else if(typeof ActiveXObject !="undefined") { //檢查activeXString if(typeof arguments.callee.activeXString!="string") { var versions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len; for(i=0,len=versions.length;i<len,i++) { try{ //看是否有能夠支持的版本 new ActiveXObject(versions[i]); arguments.callee.activeXString=versions[i]; break; } catch(ex){ //跳過 } } } //返回ActiveXObject return new ActiveXObject(arguments.callee.activeXString); } else { //都不行 throw new Error("NO XHR object availablle"); } }
這個例子先檢查XHR對象是否存在,存在就返回XHR對象,不存在就檢查ActiveX對象是否存在,存在就返回,若是兩個對象都不存在,就返回錯誤。ajax
XHR有一個方法叫open(),接收三個參數,請求方式(get,post),請求的url,表示是否異步請求的布爾值(true爲異步)跨域
let xhr=createXHR(); xhr=open('get','https://www.baidu.com',flase);
==open()方法不會直接發送請求,而是啓用一個請求以備發送==瀏覽器
XHR還有一個方法叫send(),接收一個參數,即做爲請求主體要發送的數據。
==send()和open()配合使用就能夠發送特定的請求==。服務器
xhr=open('get','https://www.baidu.com',flase); xhr.send(null);
上面代碼是同步執行的,因此要等服務器響應請求後js代碼纔會繼續執行。服務器響應後會自動爲XHR對象填充如下信息:app
屬性 | 描述 |
---|---|
responseText | 做爲響應主題被返回的文本 |
responseXML | 若是響應的內容是"text/xml"或"application/xml",這個屬性將保存響應數據的XML DOM文檔 ,若是不是xml文件,這個值爲空 |
status | HTTP的響應狀態 |
statusText | HTTP響應狀態說明 |
儘可能不要用statusText去判斷,statusText在跨域時不太可靠。異步
if((xhr.status>=200&&xhr.status<=300)||xhr.status===304) { //success console.log("status success"); } else { console.log("status fail"); }
注意:瀏覽器有時候會錯誤的報告204狀態,IE的XHR的ActiveX會將201設置爲1223,IE中原生的XHR會將204規範爲200,而opera或將status設置爲0。函數
能夠檢測XHR對象的readyState屬性來求得請求/響應的當前階段post
這些階段的改變會觸發readystatechange事件,能夠根據該事件來檢測readyState編碼
//onreadystatechange事件要在open以前指定,保證跨域瀏覽器的兼容性 xhr.onreadystatechange=function(){ if(xhr.readyState===4) { if((xhr.status>=200&&xhr.status<=300)||xhr.status===304) { //success console.log("status success"); } else { console.log("status fail"); } } } xhr.open("get","https://www.baidu.com",true); xhr.send(null);
能夠用xhr.abort()在響應前取消異步請求,
這個方法會使XHR中止觸發時間,不再容許訪問與響應有關的對象屬性,這個方法在請求終止後還會對XHR解引,不建議XHR重用,會影響內存。
xhr.open("get","www.baidu.com",true); // 不要使用瀏覽器正常字段,會影響瀏覽器響應 xhr.setRequestHeader("MyHeader","MyValue"); xhr.send(null);
var MyHeader=xhr.getResponseHeader('Content-Type'); var allHeader=xhr.getAllResponseHeader();
get請求經常使用於向服務器查詢某些信息。
//這裏的查詢字符串須要正確的編碼 xhr.open("get","example.php?name=name1&age=age1",true);
GET請求常常發生的錯誤是查詢字符串的格式問題,查詢字符串中的每一個參數名和值都須要encodeURIComponent()來先進行編碼。
/** * [對查詢字符串進行編碼] * @param {[type]} url [要添加的參數的url] * @param {[type]} name [參數名] * @param {[type]} value [參數值] */ function addURLParam(url,name,value) { url+=(url.indexOf("?")===-1?"?":"&"); url+=encodeURIComponent(name)+"="+encodeURIComponent(value); return url; }
使用這個函數能夠保證查詢字符串的格式良好,能可靠的用於XHR對象
post請求用於向服務器發送應該被保存的數據,把數據做爲請求主體提交。
post請求能夠提交XML文檔
xhr.open("post","example.php",true) xhr.send(data);
默認狀況下,服務器對post請求和Web表單提交不會一視同仁。若是須要提交表單,可使用以下代碼
/** * post提交表單 * @return {[type]} [description] */ function submitData(){ var xhr=createXHR(); xhr.onreadystatechange=function(){ if(xhr.readyState===4) { if((xhr.status>=200&&xhr.status<=300)||xhr.status===304) { //success console.log("status success"); } else { console.log("status fail"); } } } xhr.open("post","example.php",true); //設置頭部信息爲表單提交時的內容 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); var form=document.getElementById("user-info"); //將表單數據序列化 xhr.send(serialize(form)); }