摘要:把提交的數(shù)據(jù)則放置在是包的包體中。異步請(qǐng)求發(fā)送器請(qǐng)求繼續(xù)還行后面的代碼響應(yīng)結(jié)果接收完畢了操作結(jié)果,這是同步請(qǐng)求的大致過(guò)程。但是有些情況下我們還是得用同步請(qǐng)求。
上一篇文章 我們大概知道了XHR對(duì)象是什么東東,也都了解了它的一些屬性和方法,那么現(xiàn)在具體來(lái)實(shí)現(xiàn)一下Ajax技術(shù) 和 了解下XHR2對(duì)象。
1.實(shí)現(xiàn)Ajax先來(lái)創(chuàng)建個(gè)XHR對(duì)象的實(shí)例:
var xhr = function(){ if (window.XMLHttpRequest) { return new XMLHttpRequest(); }else{ return new ActiveObject("Micrsorf.XMLHttp"); } }(); console.log(xhr.readyState);
先來(lái)看個(gè)get請(qǐng)求
xhr.onreadystatechange = function(){ switch(xhr.readyState){ case 0 : console.log(0,"未初始化...."); break; case 1 : console.log(1,"請(qǐng)求參數(shù)已準(zhǔn)備,尚未發(fā)送請(qǐng)求..."); break; case 2 : console.log(2,"已經(jīng)發(fā)送請(qǐng)求,尚未接收響應(yīng)"); break; case 3 : console.log(3,"正在接受部分響應(yīng)....."); data.innerHTML = xhr.responseText; break; case 4 : console.log(4,"響應(yīng)全部接受完畢"); if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { document.write(xhr.responseText); }else{ document.write("error:" + xhr.status); } break; } } xhr.open("get","/products/getProduct?id=1"); xhr.send(null);
這里發(fā)送了個(gè)簡(jiǎn)單的get異步請(qǐng)求到我本地的web服務(wù)器中,然后我們?cè)诳刂婆_(tái)看下輸出:
可以看到剛創(chuàng)建完XHR對(duì)象后的readyState為0,當(dāng)readyState為1,2,3,4,時(shí)都觸發(fā)了onreadystatechange事件,而 readyState為0沒(méi)有觸發(fā),readyState為3時(shí)觸發(fā)了兩次,為什么這樣呢?
為什么為0時(shí)沒(méi)有觸發(fā),我們剛創(chuàng)建XHR對(duì)象后readyState為0,然后接著執(zhí)行后面的代碼,直到send()方法之前readyState的值都沒(méi)有發(fā)生改變,所以在onreadystatechange事件中檢測(cè)readyState為0是沒(méi)有意義的。
readyState為3是觸發(fā)了兩次,其實(shí)有些請(qǐng)求不止兩次,看你請(qǐng)求的數(shù)據(jù)量的大小而定,我們?cè)龃蠼邮諗?shù)據(jù)來(lái)看看:
這就好了,既然我們能在readystate為3時(shí)獲取數(shù)據(jù)的相關(guān)信息,那我們就可以利用這個(gè)特性在readystate為3時(shí)做一個(gè)數(shù)據(jù)加載進(jìn)度條變化的效果了,這個(gè)講到XHR2對(duì)象的時(shí)候來(lái)試試。
還有一個(gè)就是在發(fā)送get請(qǐng)求時(shí),get請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中),以?分割URL和傳輸數(shù)據(jù),參數(shù)之間以&相連,如:"/products/getProduct?id=1"。如果數(shù)據(jù)是英文字母/數(shù)字,原樣發(fā)送,如果是空格,轉(zhuǎn)換為+,如果是中文/其他字符,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號(hào)以16進(jìn)制表示的ASCII。
POST把提交的數(shù)據(jù)則放置在是HTTP包的包體中。
再來(lái)個(gè)post請(qǐng)求
1.先來(lái)個(gè)簡(jiǎn)單的表單,注冊(cè)一個(gè)用戶
2.用Ajax提交數(shù)據(jù)到服務(wù)器
var btn = document.getElementById("add"); btn.onclick = function(){ var tel = document.getElementById("tel").value.toString(), pwd = document.getElementById("pwd").value.toString(); var data =encodeFormData({ tel : tel, pwd : pwd }) ; xhr.onreadystatechange = function(){ switch(xhr.readyState){ case 0 : console.log(0,"未初始化...."); break; case 1 : console.log(1,"請(qǐng)求參數(shù)已準(zhǔn)備,尚未發(fā)送請(qǐng)求..."); break; case 2 : console.log(2,"正在添加...."); break; case 3 : console.log(3,"已接收數(shù)據(jù)長(zhǎng)度:"+xhr.responseText.length ); break; case 4 : console.log(4,"響應(yīng)全部接受完畢"); if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { databox.innerHTML = xhr.responseText; }else{ databox.innerHTML = "error:" + xhr.status; } break; } } xhr.open("post","/member/register"); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded") xhr.send(data); };
那么post請(qǐng)求需要注意兩個(gè)地方:
第一:
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
表單數(shù)據(jù)編碼格式有一個(gè)正式的MIME類型:pplication/x-www-form-urlencoded
當(dāng)使用post方式提交這種順序表單時(shí),必須設(shè)置Content-Type請(qǐng)求頭為這個(gè)值來(lái)模仿表單數(shù)據(jù)的提交。
第二:
var data =encodeFormData({ tel : tel, pwd : pwd }) ;
HTTP POST請(qǐng)求包含一個(gè)請(qǐng)求主體,它包含了客戶端發(fā)送給服務(wù)器的數(shù)據(jù),比如:
這里為了簡(jiǎn)單直接明文傳輸了。 這個(gè)數(shù)據(jù)比較少和簡(jiǎn)單,我們也可以直接修改上面的send()方法發(fā)送數(shù)據(jù)的方式如下:
xhr.send("tel="+tel+"&pwd="+pwd);
但是當(dāng)這個(gè)表單數(shù)據(jù)的比叫多而復(fù)雜時(shí),再以這種字符串拼接的方式傳遞的話比較容易出錯(cuò),不好維護(hù),所以我們需要封裝一個(gè)這樣的方法幫助我們將我們的數(shù)據(jù)拼接成這樣的格式:
function encodeFormData(data){ if(!data) return ""; var pairs = []; for(var name in data){ if(!data.hasOwnProperty(name)) continue; if(typeof data[name] === "function") continue; var value = data[name].toString(); name = encodeURIComponent(name.replace("%20","+")); value = encodeURIComponent(value.replace("%20","+")); pairs.push(name+"="+value); } return pairs.join("&"); }2.GET 還是 POST
get還是post,其實(shí)這和ajax是沒(méi)有關(guān)系的了,主要還是取決于這兩個(gè)請(qǐng)求方式的特點(diǎn):
通過(guò)上面的兩個(gè)ajax的實(shí)例,我們可以看出get請(qǐng)求和post請(qǐng)求的一些特點(diǎn):
get請(qǐng)求:
GET 請(qǐng)求可被緩存
GET 請(qǐng)求保留在瀏覽器歷史記錄中
GET 請(qǐng)求可被收藏為書簽
GET 請(qǐng)求不應(yīng)在處理敏感數(shù)據(jù)時(shí)使用
GET 請(qǐng)求有長(zhǎng)度限制
GET 請(qǐng)求只應(yīng)當(dāng)用于取回?cái)?shù)據(jù)
post請(qǐng)求:
POST 請(qǐng)求不會(huì)被緩存
POST 請(qǐng)求不會(huì)保留在瀏覽器歷史記錄中
POST 不能被收藏為書簽
POST 請(qǐng)求對(duì)數(shù)據(jù)長(zhǎng)度沒(méi)有要求
那,有了這個(gè)比較,你應(yīng)該知道什么時(shí)候用get什么時(shí)候用post了。
3.異步和同步ajax默認(rèn)的都是異步的請(qǐng)求,我們上面的兩個(gè)實(shí)例也是用的異步請(qǐng)求,那沒(méi)什么不用同步呢?同步和異步有什么特點(diǎn)?
同步請(qǐng)求:
發(fā)送器請(qǐng)求-->等待結(jié)果-->操作結(jié)果-->繼續(xù)還行后面的代碼 ,這是同步請(qǐng)求的大致過(guò)程,由于客服端的javascript是單線程的,也就是說(shuō)我們必須等待結(jié)果完全接收完畢之后才能繼續(xù)執(zhí)行后面的代碼,嚴(yán)格按照步驟一步一步來(lái),它通常會(huì)導(dǎo)致整個(gè)瀏覽器的UI阻塞(白屏等),如果連接服務(wù)器響應(yīng)很慢,那么用戶瀏覽器將凍結(jié),用不不能進(jìn)行其他操作。
如果我們發(fā)起一個(gè)同步請(qǐng)求,chrome瀏覽器會(huì)給你這樣一個(gè)警告:Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user"s experience. For more help, check http://xhr.spec.whatwg.org/. 意思就是同步請(qǐng)求不利于用戶體驗(yàn)。
異步請(qǐng)求:
發(fā)送器請(qǐng)求-->繼續(xù)還行后面的代碼-->響應(yīng)結(jié)果接收完畢了-->操作結(jié)果,這是同步請(qǐng)求的大致過(guò)程。
可以看到,異步請(qǐng)求在發(fā)送請(qǐng)求之后沒(méi)有等待結(jié)果的返回而是繼續(xù)執(zhí)行后面的代碼,也就是說(shuō)在結(jié)果返回之前用戶可以操作其他東西或是看到其他UI,用戶體驗(yàn)良好。但是有些情況下我們還是得用同步請(qǐng)求。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/85698.html
摘要:下面來(lái)看下具體的對(duì)象有哪些屬性和方法。對(duì)象的屬性和方法屬性請(qǐng)求的狀態(tài)響應(yīng)體不包括頭部對(duì)請(qǐng)求的響應(yīng),解析為并作為對(duì)象返回。方法取消當(dāng)前響應(yīng),關(guān)閉連接并且結(jié)束任何未決的網(wǎng)絡(luò)活動(dòng)。所以,調(diào)用對(duì)象的方法要有一定的順序,比如在方法注冊(cè)事件。 Ajax是一種能夠向服務(wù)器請(qǐng)求額外的數(shù)據(jù)而無(wú)需卸載頁(yè)面(無(wú)刷新)的技術(shù),是對(duì)Asynchronous Javascript + XML的簡(jiǎn)寫,因其良好...
摘要:注意事項(xiàng)以下版本要設(shè)置默認(rèn)編碼,,否則程序可能無(wú)法正確顯示中文。組成部分協(xié)議是對(duì)請(qǐng)求和響應(yīng)的報(bào)文內(nèi)容進(jìn)行了約束和規(guī)范。請(qǐng)求報(bào)文請(qǐng)求是由客戶端發(fā)起,其規(guī)范格式為請(qǐng)求行請(qǐng)求頭請(qǐng)求主體。 showImg(https://segmentfault.com/img/remote/1460000013696283?w=1920&h=1080); Ajax 前言 前面我們已經(jīng)學(xué)習(xí)了js基礎(chǔ)知識(shí)和一些...
摘要:注意事項(xiàng)以下版本要設(shè)置默認(rèn)編碼,,否則程序可能無(wú)法正確顯示中文。組成部分協(xié)議是對(duì)請(qǐng)求和響應(yīng)的報(bào)文內(nèi)容進(jìn)行了約束和規(guī)范。請(qǐng)求報(bào)文請(qǐng)求是由客戶端發(fā)起,其規(guī)范格式為請(qǐng)求行請(qǐng)求頭請(qǐng)求主體。 showImg(https://segmentfault.com/img/remote/1460000013696283?w=1920&h=1080); Ajax 前言 前面我們已經(jīng)學(xué)習(xí)了js基礎(chǔ)知識(shí)和一些...
摘要:一定在發(fā)送請(qǐng)求之前注冊(cè)不管同步或者異步為了讓這個(gè)事件可以更加可靠一定觸發(fā),一定是先注冊(cè)了解同步模式即可,切記不要使用同步模式。至此,我們已經(jīng)大致了解了的基本。一種數(shù)據(jù)描述手段,基本現(xiàn)在的項(xiàng)目不用了,淘汰的原因數(shù)據(jù)冗余太多。 什么是ajax? AJAX 就是瀏覽器提供的一套 API,可以通過(guò) JavaScript 調(diào)用,從而實(shí)現(xiàn)通過(guò)代碼控制請(qǐng)求與響應(yīng)。實(shí)現(xiàn)網(wǎng)絡(luò)編程 1、使用 AJAX 的...
摘要:一定在發(fā)送請(qǐng)求之前注冊(cè)不管同步或者異步為了讓這個(gè)事件可以更加可靠一定觸發(fā),一定是先注冊(cè)了解同步模式即可,切記不要使用同步模式。至此,我們已經(jīng)大致了解了的基本。一種數(shù)據(jù)描述手段,基本現(xiàn)在的項(xiàng)目不用了,淘汰的原因數(shù)據(jù)冗余太多。 什么是ajax? AJAX 就是瀏覽器提供的一套 API,可以通過(guò) JavaScript 調(diào)用,從而實(shí)現(xiàn)通過(guò)代碼控制請(qǐng)求與響應(yīng)。實(shí)現(xiàn)網(wǎng)絡(luò)編程 1、使用 AJAX 的...
閱讀 2052·2021-11-15 11:39
閱讀 3236·2021-10-09 09:41
閱讀 1500·2019-08-30 14:20
閱讀 3269·2019-08-30 13:53
閱讀 3333·2019-08-29 16:32
閱讀 3389·2019-08-29 11:20
閱讀 3029·2019-08-26 13:53
閱讀 783·2019-08-26 12:18