日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

你真的会使用XMLHttpRequest吗?

發布時間:2024/4/17 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 你真的会使用XMLHttpRequest吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么80%的碼農都做不了架構師?>>> ??

看到標題時,有些同學可能會想:“我已經用xhr成功地發過很多個Ajax請求了,對它的基本操作已經算挺熟練了。” 我之前的想法和你們一樣,直到最近我使用xhr時踩了不少坑兒,我才突然發現其實自己并不夠了解xhr,我知道的只是最最基本的使用。
于是我決定好好地研究一番xhr的真面目,可拜讀了不少博客后都不甚滿意,于是我決定認真閱讀一遍W3C的XMLHttpRequest標準。看完標準后我如同醍醐灌頂一般,感覺到了從未有過的清澈。這篇文章就是參考W3C的XMLHttpRequest標準和結合一些實踐驗證總結而來的。

Ajax和XMLHttpRequest

我們通常將Ajax等同于XMLHttpRequest,但細究起來它們兩個是屬于不同維度的2個概念。

以下是我認為對Ajax較為準確的解釋:(摘自what is Ajax)
AJAX stands for Asynchronous JavaScript and XML. AJAX is a new technique for creating better, faster, and more interactive web applications with the help of XML, HTML, CSS, and Java Script.

AJAX is based on the following open standards:

  • Browser-based presentation using HTML and Cascading Style Sheets (CSS).

  • Data is stored in XML format and fetched from the server.

  • Behind-the-scenes data fetches using XMLHttpRequest objects in the browser.

  • JavaScript to make everything happen.

從上面的解釋中可以知道:ajax是一種技術方案,但并不是一種新技術。它依賴的是現有的CSS/HTML/Javascript,而其中最核心的依賴是瀏覽器提供的XMLHttpRequest對象,是這個對象使得瀏覽器可以發出HTTP請求與接收HTTP響應。

所以我用一句話來總結兩者的關系:我們使用XMLHttpRequest對象來發送一個Ajax請求。

XMLHttpRequest的發展歷程

XMLHttpRequest一開始只是微軟瀏覽器提供的一個接口,后來各大瀏覽器紛紛效仿也提供了這個接口,再后來W3C對它進行了標準化,提出了XMLHttpRequest標準。XMLHttpRequest標準又分為Level 1和Level 2。
XMLHttpRequest Level 1主要存在以下缺點:

  • 受同源策略的限制,不能發送跨域請求;

  • 不能發送二進制文件(如圖片、視頻、音頻等),只能發送純文本數據;

  • 在發送和獲取數據的過程中,無法實時獲取進度信息,只能判斷是否完成;

那么Level 2對Level 1?進行了改進,XMLHttpRequest Level 2中新增了以下功能:

  • 可以發送跨域請求,在服務端允許的情況下;

  • 支持發送和接收二進制數據;

  • 新增formData對象,支持發送表單數據;

  • 發送和獲取數據時,可以獲取進度信息;

  • 可以設置請求的超時時間;

當然更詳細的對比介紹,可以參考阮老師的這篇文章,文章中對新增的功能都有具體代碼示例。

XMLHttpRequest兼容性

關于xhr的瀏覽器兼容性,大家可以直接查看“Can I use”這個網站提供的結果XMLHttpRequest兼容性,下面提供一個截圖。

從圖中可以看到:

  • IE8/IE9、Opera Mini 完全不支持xhr對象

  • IE10/IE11部分支持,不支持?xhr.responseType為json

  • 部分瀏覽器不支持設置請求超時,即無法使用xhr.timeout

  • 部分瀏覽器不支持xhr.responseType為blob

細說XMLHttpRequest如何使用

先來看一段使用XMLHttpRequest發送Ajax請求的簡單示例代碼。

function sendAjax() {//構造表單數據var formData = new FormData();formData.append('username', 'johndoe');formData.append('id', 123456);//創建xhr對象 var xhr = new XMLHttpRequest();//設置xhr請求的超時時間xhr.timeout = 3000;//設置響應返回的數據格式xhr.responseType = "text";//創建一個 post 請求,采用異步xhr.open('POST', '/server', true);//注冊相關事件回調處理函數xhr.onload = function(e) { if(this.status == 200||this.status == 304){alert(this.responseText);}};xhr.ontimeout = function(e) { ... };xhr.onerror = function(e) { ... };xhr.upload.onprogress = function(e) { ... };//發送數據xhr.send(formData); }

上面是一個使用xhr發送表單數據的示例,整個流程可以參考注釋。

接下來我將站在使用者的角度,以問題的形式介紹xhr的基本使用。
我對每一個問題涉及到的知識點都會進行比較細致地介紹,有些知識點可能是你平時忽略關注的。

如何設置request header

在發送Ajax請求(實質是一個HTTP請求)時,我們可能需要設置一些請求頭部信息,比如content-type、connection、cookie、accept-xxx等。xhr提供了setRequestHeader來允許我們修改請求 header。

void setRequestHeader(DOMString header, DOMString value);

注意點

  • 方法的第一個參數 header 大小寫不敏感,即可以寫成content-type,也可以寫成Content-Type,甚至寫成content-Type;

  • Content-Type的默認值與具體發送的數據類型有關,請參考本文【可以發送什么類型的數據】一節;

  • setRequestHeader必須在open()方法之后,send()方法之前調用,否則會拋錯;

  • setRequestHeader可以調用多次,最終的值不會采用覆蓋override的方式,而是采用追加append的方式。下面是一個示例代碼:

var client = new XMLHttpRequest(); client.open('GET', 'demo.cgi'); client.setRequestHeader('X-Test', 'one'); client.setRequestHeader('X-Test', 'two'); // 最終request header中"X-Test"為: one, two client.send();

如何獲取response header

xhr提供了2個用來獲取響應頭部的方法:getAllResponseHeaders和getResponseHeader。前者是獲取 response 中的所有header 字段,后者只是獲取某個指定 header 字段的值。另外,getResponseHeader(header)的header參數不區分大小寫。

DOMString getAllResponseHeaders();
DOMString getResponseHeader(DOMString header);

這2個方法看起來簡單,但卻處處是坑兒。

你是否遇到過下面的坑兒?——反正我是遇到了。。。

  • 使用getAllResponseHeaders()看到的所有response header與實際在控制臺?Network?中看到的?response header?不一樣

  • 使用getResponseHeader()獲取某個?header?的值時,瀏覽器拋錯Refused to get unsafe header "XXX"

  • 經過一番尋找最終在?Stack Overflow找到了答案。

    • 原因1:W3C的 xhr 標準中做了限制,規定客戶端無法獲取 response 中的?Set-Cookie、Set-Cookie2這2個字段,無論是同域還是跨域請求;

    • 原因2:W3C 的 cors 標準對于跨域請求也做了限制,規定對于跨域請求,客戶端允許獲取的response header字段只限于“simple response header”和“Access-Control-Expose-Headers” (兩個名詞的解釋見下方)。

    "simple response header"包括的 header 字段有:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma;
    "Access-Control-Expose-Headers":首先得注意是"Access-Control-Expose-Headers"進行跨域請求時響應頭部中的一個字段,對于同域請求,響應頭部是沒有這個字段的。這個字段中列舉的 header 字段就是服務器允許暴露給客戶端訪問的字段。

    所以getAllResponseHeaders()只能拿到限制以外(即被視為safe)的header字段,而不是全部字段;而調用getResponseHeader(header)方法時,header參數必須是限制以外的header字段,否則調用就會報Refused to get unsafe header的錯誤。

    如何指定xhr.response的數據類型

    有些時候我們希望xhr.response返回的就是我們想要的數據類型。比如:響應返回的數據是純JSON字符串,但我們期望最終通過xhr.response拿到的直接就是一個 js 對象,我們該怎么實現呢?
    有2種方法可以實現,一個是level 1就提供的overrideMimeType()方法,另一個是level 2才提供的xhr.responseType屬性。

    xhr.overrideMimeType()

    overrideMimeType是xhr level 1就有的方法,所以瀏覽器兼容性良好。這個方法的作用就是用來重寫response的content-type,這樣做有什么意義呢?比如:server 端給客戶端返回了一份document或者是?xml文檔,我們希望最終通過xhr.response拿到的就是一個DOM對象,那么就可以用xhr.overrideMimeType('text/xml; charset = utf-8')來實現。

    再舉一個使用場景,我們都知道xhr level 1不支持直接傳輸blob二進制數據,那如果真要傳輸 blob 該怎么辦呢?當時就是利用overrideMimeType方法來解決這個問題的。

    下面是一個獲取圖片文件的代碼示例:

    var xhr = new XMLHttpRequest(); //向 server 端獲取一張圖片 xhr.open('GET', '/path/to/image.png', true);// 這行是關鍵! //將響應數據按照純文本格式來解析,字符集替換為用戶自己定義的字符集 xhr.overrideMimeType('text/plain; charset=x-user-defined');xhr.onreadystatechange = function(e) {if (this.readyState == 4 && this.status == 200) {//通過 responseText 來獲取圖片文件對應的二進制字符串var binStr = this.responseText;//然后自己再想方法將逐個字節還原為二進制數據for (var i = 0, len = binStr.length; i < len; ++i) {var c = binStr.charCodeAt(i);//String.fromCharCode(c & 0xff);var byte = c & 0xff; }} };xhr.send();

    代碼示例中xhr請求的是一張圖片,通過將?response?的?content-type?改為'text/plain; charset=x-user-defined',使得?xhr?以純文本格式來解析接收到的blob 數據,最終用戶通過this.responseText拿到的就是圖片文件對應的二進制字符串,最后再將其轉換為 blob 數據。

    xhr.responseType

    responseType是xhr level 2新增的屬性,用來指定xhr.response的數據類型,目前還存在些兼容性問題,可以參考本文的【XMLHttpRequest的兼容性】這一小節。那么responseType可以設置為哪些格式呢,我簡單做了一個表,如下:

    值xhr.response?數據類型說明
    ""String字符串默認值(在不設置responseType時)
    "text"String字符串
    "document"Document對象希望返回?XML?格式數據時使用
    "json"javascript?對象存在兼容性問題,IE10/IE11不支持
    "blob"Blob對象
    "arrayBuffer"ArrayBuffer對象

    下面是同樣是獲取一張圖片的代碼示例,相比xhr.overrideMimeType,用xhr.response來實現簡單得多。

    var xhr = new XMLHttpRequest(); xhr.open('GET', '/path/to/image.png', true); //可以將`xhr.responseType`設置為`"blob"`也可以設置為`" arrayBuffer"` //xhr.responseType = 'arrayBuffer'; xhr.responseType = 'blob';xhr.onload = function(e) {if (this.status == 200) {var blob = this.response;...} };xhr.send();

    小結

    雖然在xhr level 2中,2者是共同存在的。但其實不難發現,xhr.responseType就是用來取代xhr.overrideMimeType()的,xhr.responseType功能強大的多,xhr.overrideMimeType()能做到的xhr.responseType都能做到。所以我們現在完全可以摒棄使用xhr.overrideMimeType()了。

    如何獲取response數據

    xhr提供了3個屬性來獲取請求返回的數據,分別是:xhr.response、xhr.responseText、xhr.responseXML

    • xhr.response

      • 默認值:空字符串""

      • 當請求完成時,此屬性才有正確的值

      • 請求未完成時,此屬性的值可能是""或者?null,具體與?xhr.responseType有關:當responseType為""或"text"時,值為"";responseType為其他值時,值為?null

    • xhr.responseText

      • 默認值為空字符串""

      • 只有當?responseType?為"text"、""時,xhr對象上才有此屬性,此時才能調用xhr.responseText,否則拋錯

      • 只有當請求成功時,才能拿到正確值。以下2種情況下值都為空字符串"":請求未完成、請求失敗

    • xhr.responseXML

      • 默認值為?null

      • 只有當?responseType?為"text"、""、"document"時,xhr對象上才有此屬性,此時才能調用xhr.responseXML,否則拋錯

      • 只有當請求成功且返回數據被正確解析時,才能拿到正確值。以下3種情況下值都為null:請求未完成、請求失敗、請求成功但返回數據無法被正確解析時

    如何追蹤ajax請求的當前狀態

    在發一個ajax請求后,如果想追蹤請求當前處于哪種狀態,該怎么做呢?

    用xhr.readyState這個屬性即可追蹤到。這個屬性是只讀屬性,總共有5種可能值,分別對應xhr不同的不同階段。每次xhr.readyState的值發生變化時,都會觸發xhr.onreadystatechange事件,我們可以在這個事件中進行相關狀態判斷。

    xhr.onreadystatechange = function () {switch(xhr.readyState){case 1://OPENED//do somethingbreak;case 2://HEADERS_RECEIVED//do somethingbreak;case 3://LOADING//do somethingbreak;case 4://DONE//do somethingbreak;} 值狀態描述
    0UNSENT?(初始狀態,未打開)此時xhr對象被成功構造,open()方法還未被調用
    1OPENED?(已打開,未發送)open()方法已被成功調用,send()方法還未被調用。注意:只有xhr處于OPENED狀態,才能調用xhr.setRequestHeader()和xhr.send(),否則會報錯
    2HEADERS_RECEIVED(已獲取響應頭)send()方法已經被調用, 響應頭和響應狀態已經返回
    3LOADING?(正在下載響應體)響應體(response entity body)正在下載中,此狀態下通過xhr.response可能已經有了響應數據
    4DONE?(整個數據傳輸過程結束)整個數據傳輸過程結束,不管本次請求是成功還是失敗

    如何設置請求的超時時間

    如果請求過了很久還沒有成功,為了不會白白占用的網絡資源,我們一般會主動終止請求。XMLHttpRequest提供了timeout屬性來允許設置請求的超時時間。

    xhr.timeout

    單位:milliseconds 毫秒
    默認值:0,即不設置超時

    很多同學都知道:從請求開始?算起,若超過?timeout?時間請求還沒有結束(包括成功/失敗),則會觸發ontimeout事件,主動結束該請求。

    【那么到底什么時候才算是請求開始??】
    ——xhr.onloadstart事件觸發的時候,也就是你調用xhr.send()方法的時候。
    因為xhr.open()只是創建了一個連接,但并沒有真正開始數據的傳輸,而xhr.send()才是真正開始了數據的傳輸過程。只有調用了xhr.send(),才會觸發xhr.onloadstart?。

    【那么什么時候才算是請求結束??】
    ——?xhr.loadend事件觸發的時候。

    另外,還有2個需要注意的坑兒:

  • 可以在?send()之后再設置此xhr.timeout,但計時起始點仍為調用xhr.send()方法的時刻。

  • 當xhr為一個sync同步請求時,xhr.timeout必須置為0,否則會拋錯。原因可以參考本文的【如何發一個同步請求】一節。

  • 如何發一個同步請求

    xhr默認發的是異步請求,但也支持發同步請求(當然實際開發中應該盡量避免使用)。到底是異步還是同步請求,由xhr.open()傳入的async參數決定。

    open(method, url [, async = true [, username = null [, password = null]]])

    • method: 請求的方式,如GET/POST/HEADER等,這個參數不區分大小寫

    • url: 請求的地址,可以是相對地址如example.php,這個相對是相對于當前網頁的url路徑;也可以是絕對地址如http://www.example.com/example.php

    • async: 默認值為true,即為異步請求,若async=false,則為同步請求

    在我認真研讀W3C 的 xhr 標準前,我總以為同步請求和異步請求只是阻塞和非阻塞的區別,其他什么事件觸發、參數設置應該是一樣的,事實證明我錯了。

    W3C 的 xhr標準中關于open()方法有這樣一段說明:

    Throws an "InvalidAccessError" exception if async is false, the JavaScript global environment is a document environment, and either the timeout attribute is not zero, the withCredentials attribute is true, or the responseType attribute is not the empty string.

    從上面一段說明可以知道,當xhr為同步請求時,有如下限制:

    • xhr.timeout必須為0

    • xhr.withCredentials必須為?false

    • xhr.responseType必須為""(注意置為"text"也不允許)

    若上面任何一個限制不滿足,都會拋錯,而對于異步請求,則沒有這些參數設置上的限制。

    之前說過頁面中應該盡量避免使用sync同步請求,為什么呢?
    因為我們無法設置請求超時時間(xhr.timeout為0,即不限時)。在不限制超時的情況下,有可能同步請求一直處于pending狀態,服務端遲遲不返回響應,這樣整個頁面就會一直阻塞,無法響應用戶的其他交互。

    另外,標準中并沒有提及同步請求時事件觸發的限制,但實際開發中我確實遇到過部分應該觸發的事件并沒有觸發的現象。如在 chrome中,當xhr為同步請求時,在xhr.readyState由2變成3時,并不會觸發?onreadystatechange事件,xhr.upload.onprogress和?xhr.onprogress事件也不會觸發。

    如何獲取上傳、下載的進度

    在上傳或者下載比較大的文件時,實時顯示當前的上傳、下載進度是很普遍的產品需求。
    我們可以通過onprogress事件來實時顯示進度,默認情況下這個事件每50ms觸發一次。需要注意的是,上傳過程和下載過程觸發的是不同對象的onprogress事件:

    • 上傳觸發的是xhr.upload對象的?onprogress事件

    • 下載觸發的是xhr對象的onprogress事件

    xhr.onprogress = updateProgress; xhr.upload.onprogress = updateProgress; function updateProgress(event) {if (event.lengthComputable) {var completedPercent = event.loaded / event.total;}}

    可以發送什么類型的數據

    void send(data);

    xhr.send(data)的參數data可以是以下幾種類型:

    • ArrayBuffer

    • Blob

    • Document

    • DOMString

    • FormData

    • null

    如果是 GET/HEAD請求,send()方法一般不傳參或傳?null。不過即使你真傳入了參數,參數也最終被忽略,xhr.send(data)中的data會被置為?null.

    xhr.send(data)中data參數的數據類型會影響請求頭部content-type的默認值:

    • 如果data是?Document?類型,同時也是HTML Document類型,則content-type默認值為text/html;charset=UTF-8;否則為application/xml;charset=UTF-8;

    • 如果data是?DOMString?類型,content-type默認值為text/plain;charset=UTF-8;

    • 如果data是?FormData?類型,content-type默認值為multipart/form-data; boundary=[xxx]

    • 如果data是其他類型,則不會設置content-type的默認值

    當然這些只是content-type的默認值,但如果用xhr.setRequestHeader()手動設置了中content-type的值,以上默認值就會被覆蓋。

    另外需要注意的是,若在斷網狀態下調用xhr.send(data)方法,則會拋錯:Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest'。一旦程序拋出錯誤,如果不 catch 就無法繼續執行后面的代碼,所以調用?xhr.send(data)方法時,應該用?try-catch捕捉錯誤。

    try{xhr.send(data)}catch(e) {//doSomething...};

    xhr.withCredentials與?CORS?什么關系

    我們都知道,在發同域請求時,瀏覽器會將cookie自動加在request header中。但大家是否遇到過這樣的場景:在發送跨域請求時,cookie并沒有自動加在request header中。

    造成這個問題的原因是:在CORS標準中做了規定,默認情況下,瀏覽器在發送跨域請求時,不能發送任何認證信息(credentials)如"cookies"和"HTTP authentication schemes"。除非xhr.withCredentials為true(xhr對象有一個屬性叫withCredentials,默認值為false)。

    所以根本原因是cookies也是一種認證信息,在跨域請求中,client端必須手動設置xhr.withCredentials=true,且server端也必須允許request能攜帶認證信息(即response header中包含Access-Control-Allow-Credentials:true),這樣瀏覽器才會自動將cookie加在request header中。

    另外,要特別注意一點,一旦跨域request能夠攜帶認證信息,server端一定不能將Access-Control-Allow-Origin設置為*,而必須設置為請求頁面的域名。

    xhr相關事件

    事件分類

    xhr相關事件有很多,有時記起來還挺容易混亂。但當我了解了具體代碼實現后,就容易理清楚了。下面是XMLHttpRequest的部分實現代碼:

    interface XMLHttpRequestEventTarget : EventTarget {// event handlersattribute EventHandler onloadstart;attribute EventHandler onprogress;attribute EventHandler onabort;attribute EventHandler onerror;attribute EventHandler onload;attribute EventHandler ontimeout;attribute EventHandler onloadend; };interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {};interface XMLHttpRequest : XMLHttpRequestEventTarget {// event handlerattribute EventHandler onreadystatechange;readonly attribute XMLHttpRequestUpload upload; };

    從代碼中我們可以看出:

  • XMLHttpRequestEventTarget接口定義了7個事件:

    • onloadstart

    • onprogress

    • onabort

    • ontimeout

    • onerror

    • onload

    • onloadend

  • 每一個XMLHttpRequest里面都有一個upload屬性,而upload是一個XMLHttpRequestUpload對象

  • XMLHttpRequest和XMLHttpRequestUpload都繼承了同一個XMLHttpRequestEventTarget接口,所以xhr和xhr.upload都有第一條列舉的7個事件

  • onreadystatechange是XMLHttpRequest獨有的事件

  • 所以這么一看就很清晰了:
    xhr一共有8個相關事件:7個XMLHttpRequestEventTarget事件+1個獨有的onreadystatechange事件;而xhr.upload只有7個XMLHttpRequestEventTarget事件。

    事件觸發條件

    下面是我自己整理的一張xhr相關事件觸發條件表,其中最需要注意的是?onerror?事件的觸發條件。

    事件觸發條件
    onreadystatechange每當xhr.readyState改變時觸發;但xhr.readyState由非0值變為0時不觸發。
    onloadstart調用xhr.send()方法后立即觸發,若xhr.send()未被調用則不會觸發此事件。
    onprogressxhr.upload.onprogress在上傳階段(即xhr.send()之后,xhr.readystate=2之前)觸發,每50ms觸發一次;xhr.onprogress在下載階段(即xhr.readystate=3時)觸發,每50ms觸發一次。
    onload當請求成功完成時觸發,此時xhr.readystate=4
    onloadend當請求結束(包括請求成功和請求失敗)時觸發
    onabort當調用xhr.abort()后觸發
    ontimeoutxhr.timeout不等于0,由請求開始即onloadstart開始算起,當到達xhr.timeout所設置時間請求還未結束即onloadend,則觸發此事件。
    onerror在請求過程中,若發生Network error則會觸發此事件(若發生Network error時,上傳還沒有結束,則會先觸發xhr.upload.onerror,再觸發xhr.onerror;若發生Network error時,上傳已經結束,則只會觸發xhr.onerror)。注意,只有發生了網絡層級別的異常才會觸發此事件,對于應用層級別的異常,如響應返回的xhr.statusCode是4xx時,并不屬于Network error,所以不會觸發onerror事件,而是會觸發onload事件。

    事件觸發順序

    當請求一切正常時,相關的事件觸發順序如下:

  • 觸發xhr.onreadystatechange(之后每次readyState變化時,都會觸發一次)

  • 觸發xhr.onloadstart
    //上傳階段開始:

  • 觸發xhr.upload.onloadstart

  • 觸發xhr.upload.onprogress

  • 觸發xhr.upload.onload

  • 觸發xhr.upload.onloadend
    //上傳結束,下載階段開始:

  • 觸發xhr.onprogress

  • 觸發xhr.onload

  • 觸發xhr.onloadend

  • 發生abort/timeout/error異常的處理

    在請求的過程中,有可能發生?abort/timeout/error這3種異常。那么一旦發生這些異常,xhr后續會進行哪些處理呢?后續處理如下:

  • 一旦發生abort或timeout或error異常,先立即中止當前請求

  • 將?readystate?置為4,并觸發?xhr.onreadystatechange事件

  • 如果上傳階段還沒有結束,則依次觸發以下事件:

    • xhr.upload.onprogress

    • xhr.upload.[onabort或ontimeout或onerror]

    • xhr.upload.onloadend

  • 觸發?xhr.onprogress事件

  • 觸發?xhr.[onabort或ontimeout或onerror]事件

  • 觸發xhr.onloadend?事件

  • 在哪個xhr事件中注冊成功回調?

    從上面介紹的事件中,可以知道若xhr請求成功,就會觸發xhr.onreadystatechange和xhr.onload兩個事件。 那么我們到底要將成功回調注冊在哪個事件中呢?我傾向于?xhr.onload事件,因為xhr.onreadystatechange是每次xhr.readyState變化時都會觸發,而不是xhr.readyState=4時才觸發。

    xhr.onload = function () {//如果請求成功if(xhr.status == 200){//do successCallback}}

    上面的示例代碼是很常見的寫法:先判斷http狀態碼是否是200,如果是,則認為請求是成功的,接著執行成功回調。這樣的判斷是有坑兒的,比如當返回的http狀態碼不是200,而是201時,請求雖然也是成功的,但并沒有執行成功回調邏輯。所以更靠譜的判斷方法應該是:當http狀態碼為2xx或304時才認為成功。

    xhr.onload = function () {//如果請求成功if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){//do successCallback}}

    結語

    終于寫完了......
    看完那一篇長長的W3C的xhr 標準,我眼睛都花了......
    希望這篇總結能幫助剛開始接觸XMLHttpRequest的你。

    最后給點擴展學習資料,如果你:

    • 想真正搞懂XMLHttpRequest,最靠譜的方法還是看?W3C的xhr 標準;

    • 想結合代碼學習如何用XMLHttpRequest發各種類型的數據,可以參考html5rocks上的這篇文章

    • 想粗略的了解XMLHttpRequest的基本使用,可以參考MDN的XMLHttpRequest介紹;

    • 想了解XMLHttpRequest?的發展歷程,可以參考阮老師的文章;

    • 想了解Ajax的基本介紹,可以參考AJAX Tutorial;

    • 想了解跨域請求,則可以參考W3C的 cors 標準;

    • 想了解http協議,則可以參考HTTP Tutorial;

    轉載于:https://my.oschina.net/mdu/blog/1510328

    總結

    以上是生活随笔為你收集整理的你真的会使用XMLHttpRequest吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 黑人巨茎大战欧美白妇 | 久久αv| 四虎影视黄色 | 欧美日本韩国一区二区三区 | 精品中文视频 | 一个色在线视频 | 日本视频免费在线播放 | 99久免费精品视频在线观78 | 在线色网站 | 欧美激情一二三 | 岛国精品一区二区 | www毛片com| 久久av高潮av | 亚洲精品1 | 特级西西444www高清大胆免费看 | 九九香蕉视频 | 久久久久国产一区二区三区潘金莲 | 欧美一级艳片视频免费观看 | 久操视频免费在线观看 | 国产成人无码一区二区在线播放 | 超碰国产97| 国产精品专区在线观看 | 国产精品网站视频 | 久久精品久久精品久久精品 | 久久亚洲精选 | 国产成人无码一区二区三区在线 | 青青青视频免费观看 | 木下凛凛子av一区二区三区 | 91久久精品日日躁夜夜躁欧美 | av青娱乐| 激情视频在线播放 | 国产 福利 在线 | 9.1成人看片 | 日韩 欧美 国产 综合 | 成人涩涩视频 | 综合久久亚洲 | 黄色无遮挡 | 中文字幕35页 | www.18av| 朋友的姐姐2在线观看 | 丁香色欲久久久久久综合网 | 日本xxxxxⅹxxxx69 | av福利在线免费观看 | 在线观看中文字幕一区 | 另类图片亚洲色图 | 国产精品黄视频 | 日韩精品高清视频 | 新天堂av| 欧美一区二区三区成人 | 国产亚洲欧美精品久久久久久 | 亚洲激情国产 | 99久久精品免费看国产交换 | 污污视频网站在线免费观看 | www在线播放| 欧美在线视频不卡 | 国产成人不卡 | 欧美日韩一区二区三区四区 | 精品无码国产一区二区三区51安 | 国产影视一区 | 岛国伊人| 91看毛片 | 人人妻人人澡人人爽欧美一区 | 国产视频一区二区三区四区 | 性视频欧美 | 91福利小视频 | 丁香婷婷六月天 | 男人与雌宠物交h | 亚洲综合日韩在线 | 公交顶臀绿裙妇女配视频 | 亚洲二级片 | 成人视屏在线 | 亚洲精品一区二区三区婷婷月 | 亚洲乱亚洲乱 | 欧美午夜精品久久久 | 台湾chinesehdxxxx少妇 | 欧美aaaaa| 国产丝袜美腿一区二区三区 | 国产日产精品一区二区 | 久久一级视频 | 国产欧美一区二 | av影视在线观看 | 国产精品伦子伦免费视频 | 五月婷婷一区二区 | 粉嫩av在线播放 | 成人不卡| 尤物网址在线观看 | 涩涩的视频在线观看 | 诱惑の诱惑筱田优在线播放 | 怡红院精品视频 | 操模特 | www.五月.com| 97视频一区二区三区 | 日产久久视频 | 麻豆视频国产精品 | 精品久久久久久久久久久久久久久久久久 | 少妇性bbb搡bbb爽爽爽欧美 | 亚洲天堂五月天 | 美国免费黄色片 | 国产精品一区二区久久 |