補充一下Ajax的使用方法
//可以復制下面兩種方法在百度上實驗 //jquery的使用方法 $.ajax({ url:"index.php", success:function(data){ //訪問到ajax取到的數據 console.log(data); } }) //原生的Ajax var xhr = new XMLHhttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText); } } xhr.open("get","index.php",true); xhr.send(null);
完美的分割線
在上家公司,我自認為我ajax用的已經非常6,因為使用jquery的ajax已經能處理各種數據與錯誤,但感覺只是會用,但是並不能說出它的所以然,也並不能說出它的五個步驟:
- 准備發送請求 (調用 new XMLHttpRequest()) (readyState == 0)
- 打開一個請求 (調用open方法) (readyState == 1)
- 發送請求 (調用send方法,並且接收到響應頭) (readyState == 2)
- 開始接受到請求 (readyState == 3)
- 接受完成 (readyState == 4)
所以我打算惡補一下ajax的基礎,雖然它可能並沒有多么高深,但是我認為以為合格的前端汪,
- 會看懂js語法會使用js才能算入門,
- 把語法基礎基本弄明白把js的每個細胞研究一遍算初級,
- 能夠思考js算中級
而此時我應該算入門到初級的中間。
Ajax核心對象XMLHttpRequest
這個對象最早在IE中被實現,不過它最早的時候是通過ActiveXObject實現的,如果不需要管兼容的話,IE9或者其他瀏覽器使用 new XMLHttpRequest() 就能創建了一個 XHR (XMLHttpRequest) 對象,IE中由於存在三個版本的XHR對象,所以如果需要兼容,需要對這三個版本進行處理,從中選出IE瀏覽器中最新支持對象:
var xhr = null; if (typeof XMLHttpRequest != undefined){ xhr = new XMLHttpRequest(); }else if(typeof ActiveXObject != undefined){ xhr = (function(){ var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"]; for (var i =0,ilen = versions.length;i<ilen;i++) { try{ //避免不支持當前版本報錯 new ActiveXObject[versions[i]]; //保存當前支持的版本 argument.callee.ActiveXString = versions[i]; } catch (e) {} } //返回一個當前瀏覽器支持的版本的XHR對象 return new ActiveXObject(argument.callee.ActiveXString); })() ; }
上面這段代碼就做了第一階段的事情,初始化一個請求
打開一個請求 open
xhr.open(); //xhr是通過new XMLHttpRequest()返回的對象 並沒有發送請求,它只定義了請求的類型,url,以及是否異步,
如: xhr.open("get","index.html",false);
第一個參數:最常見的請求類型有post和get兩種方法,
第二個參數:url如果沒有指定完整的(帶協議前綴的如: http://,https:// )url地址,那么它的地址相對當前執行代碼的頁面,
第三個參數:Ajax最優秀的地方便是可以異步同步發送請求,第三個參數false代表同步,true代表異步。
post跟get的區別
對於前端,對它能體現對大的區別就是傳參不同,get的參數放在url地址后面以 ?abc=1&bcd=2&dd=3&s=4 的形式傳遞,而post的參數放在請求主體內,通過 xhr.send() 發送, xhr.send("任何想發送給服務器的字符串");
url
url相對與執行當前代碼的頁面。
在頁面http://mydomin.com/test/obj/index.html中調用了xhr.send()表示請求在index.html頁面發送,那么url響應的地址就是http://mydomin.com/test/obj/我的請求的url地址。
如果是一個完整的地址,那么必須是同域的情況下才允許發送請求,否在會引發安全報錯,同域:同端口同協議的url地址
http://baidu.com:80
協議:http
端口:80
同步與異步的區別
同步請求必須接收完(到達第四階段)響應才會繼續往下執行代碼,
而異步請求會在發出一個請求繼續執行不會阻礙流程,
不管是同步或在異步當接收完完響應之后會調用onreadystatechange方法,當xhr屬性的readystate的值為4(第四階段)的時候表示接受完成 xhr.onreadystatechange = function(e){} ,除了第零階段,幾乎每個階段都對調用onreadystatechange方法,但取決於瀏覽器的實現。
發送一個請求 xhr.send()
xhr.send() 階段才是真真的發起請求階段,幾乎可以用來發送任何數據,在這個階段,
如果是異步請求,那么調用之后就會直接執行下面的代碼,
如果是同步請求,那么需要等到readyState的值為4也就是接收完所有響應之后才會往下執行。
接受響應
xhr對象有四個關於響應的屬性
- responseText (響應文本)
- responseXML (如果響應頭是text/xml或在application/xml那么響應數據會添加到這個屬性)
- status (響應狀態碼,200,304,404,500等等)
- statusText (響應狀態說明)
無論響應的是什么樣的內容,都會把服務器返回的內容存在 xhr.responseText 中,所以有時候只需關注 xhr.responseText ,
只有響應頭的類型是text/xml或在application/xml的時候 xhr.responseXML 才會填充響應數據
status
不同的狀態碼表示響應的狀態,
0 | 響應失敗(老版的opear可能會錯誤的把204作為0處理) |
200 | 響應成功、緩存沒有失效直接使用緩存(from cache)或者服務器響應成功 |
204 | 有些瀏覽器會錯誤的返回204,響應成功,但是沒有數據 |
304 | 響應成功,直接讀取緩存,與200(from cache)不同的是,304詢問了服務器之后,服務器告知瀏覽器緩存沒有失效可以直接使用 |
404 | 響應成功,但是沒有找到對應的資源 |
500 | 響應成功,服務器內部出現錯誤 |
statusText:表示對響應狀態的說明,不過有時候並不能准確解釋狀態,如我直接訪問一個發起一個跨域的請求的時候,statusText為空,並且每個瀏覽器對狀態的描述並不是所有的都一致。
雖然jQuery已經把所有的步驟都封裝好,讓技術員指需要關注成功與否,但很多時候了解其中的原理,處理問題會讓人更加靈活並且得心應手。