摘要:隨著對(duì)象被廣泛的接收,也開始著手制定相應(yīng)的標(biāo)準(zhǔn)來規(guī)范其行為。四設(shè)置請(qǐng)求頭每個(gè)請(qǐng)求和響應(yīng)都會(huì)帶有相應(yīng)的頭部信息,包含一些與數(shù)據(jù),收發(fā)者網(wǎng)絡(luò)環(huán)境與狀態(tài)等相關(guān)信息。該方法會(huì)令對(duì)象實(shí)例停止觸發(fā)事件,并且不再允許訪問任何和響應(yīng)有關(guān)的對(duì)象屬性。
在上一篇文章中我們知道,AJAX是一系列技術(shù)的統(tǒng)稱。在本篇中我們將更進(jìn)一步,詳細(xì)解釋如何使用Ajax技術(shù)在項(xiàng)目中獲取數(shù)據(jù)。而為了解釋清楚,我們首先要搞清楚我們是從哪里獲取數(shù)據(jù)的,其次我們關(guān)注的才是獲取數(shù)據(jù)的具體方式。
一、獲取數(shù)據(jù)我們知道AJAX用來在項(xiàng)目中以阻止頁面刷新的方式獲取數(shù)據(jù),那么數(shù)據(jù)從哪里來呢?我們又怎么知道如何獲取這些數(shù)據(jù)?答案是我們通常使用API與各式各樣的數(shù)據(jù)庫交互。
“API”是“Application Programming Interface”(即:應(yīng)用程序接口)的縮寫,你可以想象一些數(shù)據(jù)是開放的并且在等待被使用,而我們獲取這些數(shù)據(jù)的方式便是使用API。API通常的形式是一個(gè)URL,并提供指定的參數(shù)名和參數(shù)值用來幫助你定位所要獲取的數(shù)據(jù)。
還記得我們提過AJAX需要服務(wù)器端的相應(yīng)設(shè)置嗎?我們之后會(huì)再來談這一點(diǎn)。
二、AJAX技術(shù)的核心 - XMLHttpRequest對(duì)象讓我們先把服務(wù)器端的設(shè)置拋在一邊,聚焦AJAX技術(shù)的核心環(huán)節(jié):XMLHttpRequest對(duì)象。
XMLHttpRequest對(duì)象是瀏覽器提供的一個(gè)API,用來順暢地向服務(wù)器發(fā)送請(qǐng)求并解析服務(wù)器響應(yīng),當(dāng)然整個(gè)過程中,瀏覽器頁面不會(huì)被刷新。它將是本文接下來的主角,讓我們先站在較高的層次,對(duì)該對(duì)象有一個(gè)全局的概覽:
XMLHttpRequest只是一個(gè)JavaScript對(duì)象,確切的說,是一個(gè)構(gòu)造函數(shù)。換句話說,它一點(diǎn)也不神秘,它的特殊之處只在于它是由客戶端(即瀏覽器)提供的(而不是JavaScript原生的),除此之外,它有屬性,有方法,需要通過new關(guān)鍵字進(jìn)行實(shí)例化,我們只需掌握它們就好;
XMLHttpRequest對(duì)象是不斷被擴(kuò)展的。隨著XML對(duì)象被廣泛的接收,W3C也開始著手制定相應(yīng)的標(biāo)準(zhǔn)來規(guī)范其行為。目前,XMLHttpRequest有兩個(gè)級(jí)別:1級(jí)提供了XML對(duì)象的實(shí)現(xiàn)細(xì)節(jié),2級(jí)進(jìn)一步發(fā)展了XML對(duì)象,額外添加了一些方法,屬性和數(shù)據(jù)類型。但是,并不是所有瀏覽器都實(shí)現(xiàn)了XML對(duì)象2級(jí)的內(nèi)容(并不意外,對(duì)吧?);
讓我們先從剖析XMLHttpRequest實(shí)例的屬性和方法開始,先創(chuàng)建一個(gè)XML對(duì)象的實(shí)例:
const xhr = new XMLHttpRequest()
該實(shí)例的屬性,方法有:
方法.open():準(zhǔn)備啟動(dòng)一個(gè)AJAX請(qǐng)求;
.setRequestHeader():設(shè)置請(qǐng)求頭部信息;
.send():發(fā)送AJAX請(qǐng)求;
.getResponseHeader(): 獲得響應(yīng)頭部信息;
.getAllResponseHeader():獲得一個(gè)包含所有頭部信息的長字符串;
.abort():取消異步請(qǐng)求;
屬性.responseText:包含響應(yīng)主體返回文本;
.responseXML:如果響應(yīng)的內(nèi)容類型時(shí)text/xml或application/xml,該屬性將保存包含著相應(yīng)數(shù)據(jù)的XML DOM文檔;
.status:響應(yīng)的HTTP狀態(tài);
.statusText:HTTP狀態(tài)的說明;
.readyState:表示“請(qǐng)求”/“響應(yīng)”過程的當(dāng)前活動(dòng)階段
另外,瀏覽器還為該對(duì)象提供了一個(gè)onreadystatechange監(jiān)聽事件,每當(dāng)XML實(shí)例的readyState屬性變化時(shí),就會(huì)觸發(fā)該事件的發(fā)生。
至此,關(guān)于XMLHttpRequest實(shí)例對(duì)象的屬性方法就全部羅列完畢了,接下來,我們將更進(jìn)一步的探究如何使用這些方法,屬性完成發(fā)送AJAX請(qǐng)求的流程。
三、準(zhǔn)備AJAX請(qǐng)求要想與服務(wù)器交互,我們首先需要回答以下問題:
我們是要獲取數(shù)據(jù)還是存儲(chǔ)數(shù)據(jù)? --表現(xiàn)為請(qǐng)求方式的不同:GET或POST;
向哪里發(fā)出請(qǐng)求? --即相應(yīng)API地址;
以何種方式等待響應(yīng)? --有“同步”和“異步”兩種選擇;(網(wǎng)絡(luò)傳輸是一個(gè)過程,請(qǐng)求和響應(yīng)不是同時(shí)發(fā)生的。)
而XMLHttpRequest實(shí)例的.open()方法的作用就是用來回答以上三個(gè)問題。.open()方法接收三個(gè)參數(shù):請(qǐng)求方式,請(qǐng)求URL地址和是否為異步請(qǐng)求的布爾值。
下面是一個(gè).open()方法調(diào)用的例子:
// 該段代碼會(huì)啟動(dòng)一個(gè)針對(duì)“example.php”的GET同步請(qǐng)求。 xhr.open("get", "example.php", false)
相當(dāng)于開始做飯前,將工具準(zhǔn)備齊備,將菜洗好,.open()方法也同樣出色地完成了發(fā)送AJAX請(qǐng)求的準(zhǔn)備工作。
現(xiàn)在,讓我們?cè)偕钊肓牧囊恍?zhǔn)備工作的細(xì)節(jié):
(一)GET請(qǐng)求 與 POST請(qǐng)求GET請(qǐng)求
GET請(qǐng)求用于獲取數(shù)據(jù),有時(shí)候我們需要獲取的數(shù)據(jù)需要通過“查詢參數(shù)”進(jìn)行定位,在這種情況下,我們會(huì)將查詢參數(shù)追加到URL的末尾,令服務(wù)器解析。
查詢參數(shù)是指一個(gè)由?號(hào)起始,由&符號(hào)分割的包含相應(yīng)鍵值對(duì)的字符串。用來告知瀏覽器所要查詢的特定資源。
const query = "example.php?name=tom&age=24" // "?name=tom&age=24"即是一個(gè)查詢參數(shù)
需要注意的是,查詢字符串中每個(gè)參數(shù)的名和值都必須使用encodeURIComponent()進(jìn)行編碼(這是因?yàn)閁RL中有些字符會(huì)引起歧義,例如“&”)。
POST請(qǐng)求
POST請(qǐng)求用于向服務(wù)器發(fā)送應(yīng)該被保存的數(shù)據(jù),因此POST請(qǐng)求天然比GET請(qǐng)求多需要一份需要被保存的數(shù)據(jù)。那么這些數(shù)據(jù)應(yīng)該放在何處呢?畢竟,我們的.open()方法接收的三個(gè)參數(shù)都沒有合適的位置。
答案是需要發(fā)送的數(shù)據(jù)會(huì)作為.send()方法的參數(shù)最終被發(fā)往服務(wù)器,該數(shù)據(jù)可以是任意大小,任意類型。
這里需要注意以下兩點(diǎn):
.send()方法的參數(shù)是不可為空的,也就是說,對(duì)于不需要發(fā)送任何數(shù)據(jù)的GET請(qǐng)求,也需要在調(diào)用.send()方法時(shí),向其傳入null值;
目前為止,我們知道了兩種向服務(wù)器發(fā)送數(shù)據(jù)的方式:表單提交以及發(fā)送POST請(qǐng)求,要注意服務(wù)器對(duì)待這兩種方式并不一視同仁,這意味著服務(wù)器需要有相應(yīng)的代碼專門處理POST請(qǐng)求發(fā)送來的原始數(shù)據(jù)。
但好在我們可以通過POST請(qǐng)求模擬表單提交,只需要簡單兩步:
設(shè)置請(qǐng)求頭參數(shù):Content-Type: application/x-www-form-urlencoded(表單提交時(shí)的內(nèi)容類型);
將表單數(shù)據(jù)序列化為查詢字符串形式,傳入.send()方法;
(二)請(qǐng)求URL地址這里需要注意若使用相對(duì)路徑,請(qǐng)求URL是相對(duì)于執(zhí)行代碼的當(dāng)前頁面。
(三)同步請(qǐng)求與異步請(qǐng)求人們通常認(rèn)為AJAX是異步的,實(shí)際上并非如此,AJAX是避免頁面在獲取數(shù)據(jù)后刷新的一種技術(shù),至于等待服務(wù)器響應(yīng)的方式是同步還是異步,需要開發(fā)人員結(jié)合業(yè)務(wù)需求進(jìn)行配置(雖然通常是異步的)。
你可能會(huì)好奇,什么時(shí)候我們需要使用同步的AJAX?就我個(gè)人經(jīng)驗(yàn)而言,似乎很難找到相應(yīng)的場景。Stack Overflow上有一個(gè)類似的問題,有興趣的不妨點(diǎn)擊查看。
最后我們?cè)俸唵谓忉屢幌隆巴健钡却憫?yīng)與“異步”等待響應(yīng)的區(qū)別:“同步”意味著一旦請(qǐng)求發(fā)出,任何后續(xù)的JavaScript代碼不會(huì)再執(zhí)行,“異步”則是當(dāng)請(qǐng)求發(fā)出后,后續(xù)的JavaScript代碼會(huì)繼續(xù)執(zhí)行,當(dāng)請(qǐng)求成功后,會(huì)調(diào)用相應(yīng)的回調(diào)函數(shù)。
四、設(shè)置請(qǐng)求頭每個(gè)HTTP請(qǐng)求和響應(yīng)都會(huì)帶有相應(yīng)的頭部信息,包含一些與數(shù)據(jù),收發(fā)者網(wǎng)絡(luò)環(huán)境與狀態(tài)等相關(guān)信息。XMLHttpRequest對(duì)象提供的.setRequestHeader()方法為開發(fā)者提供了一個(gè)操作這兩種頭部信息的方法,并允許開發(fā)者自定義請(qǐng)求頭的頭部信息。
默認(rèn)情況下,當(dāng)發(fā)送AJAX請(qǐng)求時(shí),會(huì)附帶以下頭部信息:
Accept:瀏覽器能夠處理的內(nèi)容類型;
Accept-Charset: 瀏覽器能夠顯示的字符集;
Accept-Encoding:瀏覽器能夠處理的壓縮編碼;
Accept-Language:瀏覽器當(dāng)前設(shè)置的語言;
Connection:瀏覽器與服務(wù)器之間連接的類型;
Cookie:當(dāng)前頁面設(shè)置的任何Cookie;
Host:發(fā)出請(qǐng)求的頁面所在的域;
Referer:發(fā)出請(qǐng)求的頁面URI;
User-Agent:瀏覽器的用戶代理字符串;
注意,部分瀏覽器不允許使用.setRequestHeader()方法重寫默認(rèn)請(qǐng)求頭信息,因此自定義請(qǐng)求頭信息是更加安全的方法:
// 自定義請(qǐng)求頭 xhr.setRequestHeader("myHeader", "MyValue")五、發(fā)送請(qǐng)求
到此為止,我們已經(jīng)完全做好了發(fā)送請(qǐng)求的所有準(zhǔn)備:利用.open()方法確定了請(qǐng)求方式,等待響應(yīng)的方式和請(qǐng)求地址,甚至還通過.setRequestHeader()自定義了響應(yīng)頭,接下來就到了最激動(dòng)人心的時(shí)刻:使用.send()方法,發(fā)送AJAX請(qǐng)求!
// 發(fā)送AJAX請(qǐng)求! const xhr = new XMLHttpRequest() xhr.open("get", "example.php", false) xhr.setRequestHeader("myHeader", "goodHeader") xhr.send(null)
呃,簡單的有些令人尷尬不是嗎?換個(gè)POST請(qǐng)求試試看:
// 發(fā)送AJAX請(qǐng)求! const xhr = new XMLHttpRequest() xhr.open("post", "example.php", false) xhr.setRequestHeader("myHeader", "bestHeader") xhr.send(some_data)
額..,總覺得還是差點(diǎn)什么?放輕松伙計(jì),因?yàn)槲覀冎皇前l(fā)出了請(qǐng)求,還沒有處理響應(yīng),我們這就來看看它。
六、處理響應(yīng)讓我們直接看看如何處理一個(gè)同步的GET請(qǐng)求響應(yīng):
const xhr = new XMLHttpRequest() xhr.open("get", "example.php", false) xhr.setRequestHeader("myHeader", "goodHeader") xhr.send(null) // 由于是同步的AJAX請(qǐng)求,因此只有當(dāng)服務(wù)器響應(yīng)后才會(huì)繼續(xù)執(zhí)行下面的代碼 // 因此xhr.status的值一定不為默認(rèn)值 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { alert(xhr.responseText) } else { alert("Request was unsuccessful: " + xhr.status) }
上面的代碼不難理解,我們通過之前提到的xhr.status屬性(如果你忘記了,它存儲(chǔ)著響應(yīng)的HTTP狀態(tài))判斷請(qǐng)求是否成功,如果成功的話,我們將讀取xhr.responseText屬性中存儲(chǔ)的返回值。但是,當(dāng)我們的請(qǐng)求為異步時(shí),問題就稍微變得復(fù)雜了,由于是異步的請(qǐng)求,在xhr.send(null)語句被執(zhí)行后,JavaScript引擎會(huì)緊接著執(zhí)行下面的判斷語句,而這時(shí)由于尚未來得及響應(yīng),我們注定會(huì)得到一個(gè)默認(rèn)的xhr.status值,因此,我們永遠(yuǎn)都不可能獲取請(qǐng)求的資源了。
如何解決這個(gè)問題?答案是通過為XMLHTTPRequest實(shí)例添加onreadystatechange事件處理程序(當(dāng)然你也可以直接使用DOM2級(jí)規(guī)范規(guī)定的.addEventListener()方法,但是注意,IE8是不支持該方法的)。
xhr實(shí)例的readystatechange事件會(huì)監(jiān)聽xhr.readyState屬性的變化,你可以將這個(gè)屬性想象為一個(gè)計(jì)數(shù)器,隨著AJAX流程的推進(jìn)而不斷累加,其可取的值如下:
0:未初始化 -- 尚未調(diào)用.open()方法;
1:啟動(dòng) -- 已經(jīng)調(diào)用.open()方法,但尚未調(diào)用.send()方法;
2:發(fā)送 -- 已經(jīng)調(diào)用.send()方法,但尚未接收到響應(yīng);
3:接收 -- 已經(jīng)接收到部分響應(yīng)數(shù)據(jù);
4:完成 -- 已經(jīng)接收到全部響應(yīng)數(shù)據(jù),而且已經(jīng)可以在客戶端使用了;
有了這個(gè)時(shí)間處理程序?qū)JAX進(jìn)程做監(jiān)聽,剩下的事就簡單多了,一個(gè)異步的GET請(qǐng)求代碼如下:
const xhr = new XMLHttpRequest() xhr.onreadystatechange = () => { if (xhr.readystate == 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { alert(xhr.responseText) } else { alert("Request was unsuccessful: " + xhr.status) } } } xhr.open("get", "example.php", true) xhr.send(null)
注意:為了確保跨瀏覽器的兼容性,必須要在調(diào)用.open()方法之前指定事件處理程序,仔細(xì)想想也有道理,畢竟.open()方法的執(zhí)行也包含在該事件處理程序的監(jiān)聽范圍之內(nèi)對(duì)吧?
七、取消異步請(qǐng)求有時(shí)候,你可能需要在接收到響應(yīng)之前取消異步請(qǐng)求,這時(shí)候,你需要調(diào)用.abort()方法。
該方法會(huì)令XHR對(duì)象實(shí)例停止觸發(fā)事件,并且不再允許訪問任何和響應(yīng)有關(guān)的對(duì)象屬性。沒了監(jiān)控器,我們?cè)僖矝]法判斷響應(yīng)了不是嗎?
但是需要注意的是,當(dāng)終止AJAX請(qǐng)求后,你需要手動(dòng)對(duì)XHR對(duì)象實(shí)例進(jìn)行解綁以釋放內(nèi)存空間。
?? 恭喜你!到這里你已經(jīng)學(xué)會(huì)了所有的AJAX基礎(chǔ)知識(shí),你知道了AJAX是什么,存在的意義以及如何真正發(fā)起一個(gè)AJAX請(qǐng)求并接收響應(yīng),你已經(jīng)是一個(gè)AJAX大師!祝賀你!太棒了!??
? 真棒,尊敬的AJAX大師,你居然還沒有離開,那么我將傳授你最后一部分AJAX秘籍,幫助你成為一個(gè)真正的AJAX忍者,這是你的堅(jiān)持贏得的!
八、秘籍:XMLHttpRequest 2級(jí)還記得我們一開始有提到,W3C提出了XMLHttpRequest 2級(jí)規(guī)范嗎?雖然并非所有的瀏覽器都實(shí)現(xiàn)了該規(guī)范所規(guī)定的內(nèi)容,但還是有一些內(nèi)容被全部或大多數(shù)瀏覽器所實(shí)現(xiàn)。想成為AJAX忍者?往下看吧。
提示:在這一部分,你將會(huì)看到很多有關(guān)瀏覽器兼容性的文字,希望你不要覺得枯燥,畢竟這可是忍者的修行,對(duì)吧?
(一)FormData 類型FormData是XMLHttpRequest 2級(jí)為我們提供的新的數(shù)據(jù)類型(構(gòu)造函數(shù)),還記的我們之前是如何偽裝一個(gè)POST請(qǐng)求為一個(gè)表單提交嗎?FormData令這一過程變得更加輕松,因?yàn)閄HR對(duì)象能夠識(shí)別傳入的數(shù)據(jù)類型是FormData的實(shí)例,并自動(dòng)配置適當(dāng)?shù)念^部信息。
FormData的使用方式如下:
// 添加數(shù)據(jù) let data1 = new FormData() data1.append("name", "Tom") xhr.send(data1) // 提取表單數(shù)據(jù) let data2 = new FormData(document.forms[0]) xhr.send(data2)
除此之外,F(xiàn)ormData的另一個(gè)好處是相較于傳統(tǒng)的AJAX請(qǐng)求,它允許我們上傳二進(jìn)制數(shù)據(jù)(圖片,視頻,音頻等),具體詳情可查看該鏈接。
FormData的瀏覽器兼容性:
桌面端
IE 10+ 與其他瀏覽器均支持
移動(dòng)端
Android,F(xiàn)irefox Mobile,OperaMobile均支持,其余瀏覽器未知
(二)超時(shí)設(shè)定當(dāng)我們發(fā)送一個(gè)AJAX請(qǐng)求,卻遲遲得不到服務(wù)器響應(yīng),這種感覺是很糟糕的。為了緩解這種糟糕的感覺,XMLHttpRequest 2級(jí)規(guī)范為我們提供了一個(gè)額外的屬性和事件監(jiān)聽事件:
timeout屬性:設(shè)置超時(shí)時(shí)間,單位為毫秒;
timeout事件:當(dāng)響應(yīng)時(shí)間超出實(shí)例對(duì)象timeout屬性時(shí)被觸發(fā);
使用方式如下:
// 當(dāng)響應(yīng)時(shí)間超過1秒時(shí),請(qǐng)求中止,彈出提示框 xhr.timeout = 1000 xhr.ontimeout = () => { alert("Request did not return in a second.") }
注意,當(dāng)請(qǐng)求終止時(shí),會(huì)調(diào)用ontimeout事件處理程序,此時(shí)xhr的readyState屬性的值可能已變?yōu)?,這意味著會(huì)繼續(xù)調(diào)用onreadystatechange事件處理程序,但是當(dāng)超時(shí)中止請(qǐng)求后再訪問xhr的status屬性會(huì)使瀏覽器拋出一個(gè)錯(cuò)誤,因此需要將檢查status屬性的語句放入try-catch語句中。
雖然帶來了一些麻煩,但是我們卻對(duì)XMLHttpRequest對(duì)象有了更多的控制。
瀏覽器兼容性:
桌面端
IE 10+ 與其他瀏覽器均支持
移動(dòng)端
IE Mobile 10+ 與其他瀏覽器均支持
(三)overrideMimeType()方法響應(yīng)返回的響應(yīng)頭里,描述了返回?cái)?shù)據(jù)的MIME類型,瀏覽器通過識(shí)別該類型,告知XMLHttpRequest實(shí)例處理該數(shù)據(jù)的方式。然而有時(shí)候(例如將XML類型數(shù)據(jù)當(dāng)做純文本處理),我們想要以我們想要的方式處理響應(yīng)的數(shù)據(jù),在XMLHttpRequest 2級(jí)規(guī)范中,我們可以使用.overrideMimeType()方法,從方法名也可以輕松猜出,該方法可以覆寫響應(yīng)頭所描述數(shù)據(jù)的MIME類型。
其寫法如下:
const xhr = new XMLHttpRequest() xhr.open("get", "example.php", true) xhr.overrideMimeType("text/xml") // 強(qiáng)迫瀏覽器將響應(yīng)數(shù)據(jù)以指定類型方式解讀 xhr.send(null)
至此,我們掌控了響應(yīng)數(shù)據(jù)的處理方式。
瀏覽器兼容性:
桌面端
IE 7+ 與其他瀏覽器均支持
移動(dòng)端
Firefox Mobile,Chrome for Android 均支持,其余瀏覽器未知
(四)進(jìn)度事件Progress Events規(guī)范是W3C制定的一個(gè)工作草案。該規(guī)范定義了與客戶端與服務(wù)器通信相關(guān)的一系列事件,這些事件監(jiān)聽了通信進(jìn)程中的各個(gè)關(guān)鍵節(jié)點(diǎn),使我們能夠以更細(xì)的顆粒度掌控?cái)?shù)據(jù)傳輸過程中的細(xì)節(jié)。目前共有6個(gè)進(jìn)度事件,他們會(huì)隨數(shù)據(jù)傳輸進(jìn)展被順序觸發(fā)(除了error,abort事件),讓我們看看他們的定義和瀏覽器兼容情況:
loadstart:在接收到響應(yīng)數(shù)據(jù)的第一個(gè)字節(jié)時(shí)觸發(fā);
桌面端:除 Safari Mobile 未知外,其他瀏覽器均支持
移動(dòng)端:除 Safari Mobile 未知外,其他瀏覽器均支持
progress:在接收響應(yīng)期間持續(xù)不斷地觸發(fā);
桌面端:IE10+ 與其他瀏覽器均支持
移動(dòng)端:均支持
error:在請(qǐng)求發(fā)生錯(cuò)誤時(shí)觸發(fā);
桌面端:所有瀏覽器均支持(信息來源)
移動(dòng)端:除IE Mobile不支持外,其他瀏覽器均支持(信息來源)
abort:再因?yàn)檎{(diào)用abort()方法時(shí)觸發(fā);
桌面端:未知
移動(dòng)端:未知
load:在接收到完整的響應(yīng)數(shù)據(jù)時(shí)觸發(fā);
桌面端:IE7+ 與其他瀏覽器均支持
移動(dòng)端:Chrome for Android,Edge,F(xiàn)irefox Mobile支持,其余瀏覽器未知
loadend:在通信完成或者觸發(fā)error,abort或load事件后觸發(fā);
桌面端:所有瀏覽器不支持
移動(dòng)端:所有瀏覽器不支持
這里我們將著重展開講解以下兩個(gè)事件:
① load事件
該事件幫助我們節(jié)省了readstatechange事件,我們不必在XHR對(duì)象實(shí)例上綁定該事件監(jiān)聽函數(shù)以追蹤實(shí)例上readState屬性的變化,而是可以直接使用以下代碼:
const xhr = new XMLHttpRequest() xhr.onload = () => { if ((xhr.status >= 200 && xhr.status <300) || xhr.status == 304) { alert(xhr.responseText) } else { alert("Something wrong!") } } xhr.open("get", "example.php", true) xhr.send(null)
② progress事件
該事件令我們可以實(shí)現(xiàn)我們夢(mèng)寐以求的加載進(jìn)度條效果。因?yàn)?b>onprogress事件處理程序會(huì)接收到一個(gè)event對(duì)象,其target屬性為XHR對(duì)象實(shí)例,但卻額外包含著三個(gè)屬性:
lengthComputable:表示進(jìn)度信息是否可用的布爾值;
position:表示目前接收的字節(jié)數(shù);
totalSize:表示根據(jù)Content-Length響應(yīng)頭部確定的預(yù)期字節(jié)數(shù);
很顯然,我們的加載進(jìn)度條所需的一切資源都準(zhǔn)備就緒,我們只需寫出下面的代碼:
const xhr = new XMLHttpRequest() xhr.onload = () => { if ((xhr.status >= 200 && xhr.status <300) || xhr.status == 304) { alert(xhr.responseText) } else { alert("Something wrong!") } } // 加載進(jìn)度條 xhr.onprogress = function(event) { const divStatus = document.getElementById("status") if (event.lengthComputable) { divStatus.innerHTML = `Received ${event.postion} of ${event.totalSize} bytes` } } xhr.open("get", "example.php", true) xhr.send(null)
一切大功告成!不過還要記得注意,需要在.open()方法前調(diào)用onprogress事件處理程序。
太棒了,關(guān)于AJAX,我已經(jīng)沒有什么可說的了,如果你已經(jīng)掌握了以上所有概念,那么“AJAX忍者”的稱號(hào)你當(dāng)之無愧。
我真的為你感到驕傲,Great Work!?
? Hey!喜歡這篇文章嗎?別忘了在下方? 點(diǎn)贊讓我知道。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/90114.html
摘要:需要注意的是,并不是的替代品,兩者各自有其適應(yīng)的場景。但為了方便交流,我們通常將獲取資源的一方稱為客戶端主要的工具是瀏覽器,而將派發(fā)資源的一方稱為服務(wù)端又稱為服務(wù)器。它可以幫助我們?yōu)橹蟾拍罴?xì)節(jié)的學(xué)習(xí)打下良好基礎(chǔ)。 再也不學(xué)AJAX了是一個(gè)與AJAX主題相關(guān)的文章系列,包含以下三個(gè)部分的內(nèi)容: AJAX概述:主要回答AJAX是什么這個(gè)問題; 使用AJAX:介紹如何通過JavaSc...
摘要:一基于維基百科的定義,是一種在單個(gè)連接上進(jìn)行全雙工通訊的協(xié)議。讓我們看看這個(gè)模型的具體實(shí)現(xiàn)下面是客戶端告知服務(wù)端要升級(jí)為協(xié)議的報(bào)頭下面是服務(wù)端向客戶端返回的響應(yīng)報(bào)頭想知道這些報(bào)頭中的字段中代表什么可以參考維基百科下的說明。 讓我們先簡單回顧一下之前談到的內(nèi)容,AJAX是一種無頁面刷新的獲取服務(wù)器資源的混合技術(shù)。而基于瀏覽器的同源策略,不同域之間不可以發(fā)送AJAX請(qǐng)求。但是在某些情境下,...
摘要:瀏覽器的同源策略瀏覽器所遵守的同源策略是指限制不同源之間執(zhí)行特定操作。這正是同源策略想要規(guī)避的安全隱患。目前為止,你已經(jīng)充分了解同源策略這個(gè)主題。 我們之前提到過,AJAX技術(shù)使開發(fā)者能夠?qū)W⒂诨ヂ?lián)網(wǎng)中數(shù)據(jù)的傳輸,而不再拘泥于數(shù)據(jù)傳輸?shù)妮d體。通過AJAX技術(shù),我們獲取數(shù)據(jù)的方式變得更加靈活,可控和優(yōu)雅。 但是AJAX技術(shù)并不是一把萬能鑰匙,互聯(lián)網(wǎng)中的數(shù)據(jù)隱私和數(shù)據(jù)安全(例如你的銀行賬號(hào)...
摘要:瀏覽器的同源策略固然保障了互聯(lián)網(wǎng)世界的數(shù)據(jù)隱私與數(shù)據(jù)安全,但是如果當(dāng)我們需要使用跨域請(qǐng)求資源時(shí),同源策略又會(huì)成為開發(fā)者的阻礙。我們之前提到過,如果想要繞過瀏覽器同源策略,實(shí)現(xiàn)使用技術(shù)跨域獲取資源,需要服務(wù)端和客戶端的協(xié)同合作。 瀏覽器的同源策略固然保障了互聯(lián)網(wǎng)世界的數(shù)據(jù)隱私與數(shù)據(jù)安全,但是如果當(dāng)我們需要使用AJAX跨域請(qǐng)求資源時(shí),同源策略又會(huì)成為開發(fā)者的阻礙。在本文中,我們會(huì)簡單介紹需...
摘要:請(qǐng)求數(shù)據(jù)流程與領(lǐng)導(dǎo)想找小李匯報(bào)一下工作類似。表示從客戶端發(fā)來的請(qǐng)求在服務(wù)器端被正常處理了。表示永久性重定向。該狀態(tài)碼表示請(qǐng)求的資源已被分配了新的,以后應(yīng)使用資源現(xiàn)在所指的。表示服務(wù)器端在執(zhí)行請(qǐng)求時(shí)發(fā)生了錯(cuò)誤。 前言 AJAX即Asynchronous Javascript And XML,是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。AJAX 是一種用于創(chuàng)建快速動(dòng)態(tài)網(wǎng)頁的技術(shù)。它可以令開發(fā)...
閱讀 3576·2023-04-25 14:20
閱讀 1200·2021-09-10 10:51
閱讀 1157·2019-08-30 15:53
閱讀 464·2019-08-30 15:43
閱讀 2319·2019-08-30 14:13
閱讀 2797·2019-08-30 12:45
閱讀 1209·2019-08-29 16:18
閱讀 1169·2019-08-29 16:12