原生的Ajax实现
原生的Ajax實(shí)現(xiàn)步驟
1.原生js中的構(gòu)造函數(shù)XMLHTTPRequest()構(gòu)造實(shí)例;
考慮兼容問題: if(window.XMLHttpRequest){var xhr = new XMLHTTPRequest(); }else{var xhr = new ActiveXObject(); } 復(fù)制代碼2.實(shí)例化為對(duì)象后,要?jiǎng)?chuàng)建一個(gè)請(qǐng)求,準(zhǔn)備好一個(gè)請(qǐng)求的發(fā)射窗口狀態(tài);
xhr.open("get/post", "請(qǐng)求地址", true); 復(fù)制代碼3.send方法發(fā)出請(qǐng)求,參數(shù)是發(fā)送的報(bào)文體,get方法時(shí)報(bào)文體為空null,post方法才有內(nèi)容;
xhr.send(null); 復(fù)制代碼4.JS中需要監(jiān)聽數(shù)據(jù)什么時(shí)候回來的機(jī)制,使用一個(gè)事件監(jiān)聽就緒狀態(tài),當(dāng)xhr的狀態(tài)改變是觸發(fā);
xhr.onreadystatechange = function(){if(xhr.readyState == 4){//xhr的readyState有5個(gè)數(shù)值,表示不同狀態(tài),4表示接受文件完成,{}內(nèi)表示接受完成之后執(zhí)行的操作document.getElementById().innerHTML = xhr.responseText;} } 復(fù)制代碼狀態(tài)的監(jiān)聽要放在創(chuàng)建實(shí)例對(duì)象和open調(diào)用之間,確切的說添加事件應(yīng)該是第二步,
-
readyState的屬性值:
0: 未初始化,此時(shí)XMLHTTPRequest對(duì)象已經(jīng)創(chuàng)建,還沒有調(diào)用open();
1: 已經(jīng)創(chuàng)建請(qǐng)求,調(diào)用open函數(shù),但是還沒有調(diào)用send發(fā)送;
2: 請(qǐng)求已經(jīng)發(fā)送,正在處理中,此時(shí)已經(jīng)接受了response的報(bào)文頭部;
3: 請(qǐng)求處理中,此時(shí)已經(jīng)接收了部分報(bào)文體,response中的部分?jǐn)?shù)據(jù)已經(jīng)可以使用;
4: 響應(yīng)完成,可以使用報(bào)文的全部信息。
-
注意:為了防止緩存(304),調(diào)用open時(shí),在第二個(gè)參數(shù)請(qǐng)求地址后添加一個(gè)隨機(jī)數(shù),保證每次訪問的地址不同,避免因?yàn)榫彺鎸?dǎo)致請(qǐng)求的文件發(fā)生改變,而頁(yè)面并未隨之改變(因?yàn)槭褂昧司彺娴臄?shù)據(jù))。
post請(qǐng)求和get請(qǐng)求的區(qū)別
xhr.open("post", "請(qǐng)求文件", true);//設(shè)置請(qǐng)求頭部發(fā)送時(shí)的文本格式,因?yàn)閜ost方法只能通過表單格式發(fā)送 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");//send方法中的參數(shù)是報(bào)文體,而post方法傳遞是通過報(bào)文體,調(diào)用send方法傳遞的參數(shù)是以kv對(duì)形式的字符串,類似query string xhr.send("k=v&k=v"); 復(fù)制代碼原生的post是將傳遞的參數(shù)放到send()中以form data形式傳遞,而原生的get方法是將數(shù)據(jù)放到第二個(gè)參數(shù)的路徑?后面,以查詢字符串的形式傳遞,這和jQuery的傳遞方法不同,jQuery中的$.get()和$.post()都是通過第二個(gè)參數(shù)以json的形式傳遞到接口頁(yè)面的。 在接口頁(yè)面中,比如PHP頁(yè)面中,獲取傳遞的數(shù)據(jù)方法
$getdata = $_GET["k值"]; $postdata = $_POST["k值"]; 復(fù)制代碼但是通常參數(shù)是以json形式傳遞的,如何將json對(duì)象轉(zhuǎn)換為鍵值對(duì)形式的字符串?
var data = {"names": "Tom","age": 19,"sex": "男" }//封裝一個(gè)格式轉(zhuǎn)換函數(shù) function changeToString(JSON){var tempArr = [];for(var k in JSON){//url只允許英文、數(shù)字和特殊字符,當(dāng)有中文或其他國(guó)家語言出現(xiàn)時(shí),要通過uri(統(tǒng)一資源標(biāo)識(shí)符)來轉(zhuǎn)換tempArr.push(k + "=" + encodeURIComponent(JSON[k]));}return temp.join("&"); }//調(diào)用函數(shù)轉(zhuǎn)換格式 xhr.send(changeToString(data)); 復(fù)制代碼那么從后臺(tái)發(fā)送來的數(shù)據(jù),前端并不知道數(shù)據(jù)是什么格式,也就不能直接拿來就使用,要先進(jìn)行判斷:
如果負(fù)責(zé)的后臺(tái)在接口文件中將數(shù)組轉(zhuǎn)換為json對(duì)象再發(fā)回前端,那么前端只要做判斷就可以了。
<?php//header('Content-type: application/json');$arr = array(...);//json_encode將數(shù)組變?yōu)閖son對(duì)象形式echo json_encode($arr); ?> 復(fù)制代碼- 判斷方法一:使用JSON.parse()方法將字符串轉(zhuǎn)換為json對(duì)象,但是有兼容問題存在,IE6,7,8不兼容這個(gè)方法。
- 判斷方法二:使用eval()方法,沒有兼容問題,eval()可以將str變成執(zhí)行語句,但是轉(zhuǎn)換對(duì)象形式的字符串要注意,字符串外面必須加括號(hào)。
- 判斷方法三:使用內(nèi)置構(gòu)造函數(shù)Function(), 通過構(gòu)造函數(shù)new的實(shí)例立即執(zhí)行返回json對(duì)象。
構(gòu)造函數(shù)的參數(shù)當(dāng)有多個(gè)時(shí),最后一個(gè)為執(zhí)行語句,前面的都是參數(shù),而當(dāng)只有一個(gè)時(shí),這個(gè)參數(shù)就是執(zhí)行語句,立即調(diào)用執(zhí)行可以直接返回。
原生的Ajax可能在平時(shí)用到并不多,因?yàn)橛邢駄Query這些提供了更方便的方法,但還是要知道是怎樣實(shí)現(xiàn)的。Ajax另一個(gè)重要的概念是跨域的問題,等學(xué)完再專門寫一篇跨域的小結(jié)。
轉(zhuǎn)載于:https://juejin.im/post/5a50e3f9518825733c13df3a
總結(jié)
- 上一篇: jQuery的Ajax方法实现注册邮箱时
- 下一篇: ajax、offset