黄a在线观看-黄a在线-黄a大片-黄色片在线看-黄色毛片免费-黄色大片网站

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

JS XMLHttpRequest原理與使用方法深入詳解

瀏覽:129日期:2024-05-10 13:00:57

本文實(shí)例講述了JS XMLHttpRequest原理與使用方法。分享給大家供大家參考,具體如下:

你真的會(huì)使用XMLHttpRequest嗎?

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

Ajax和XMLHttpRequest

我們通常將Ajax等同于XMLHttpRequest,但細(xì)究起來(lái)它們兩個(gè)是屬于不同維度的2個(gè)概念。

以下是我認(rèn)為對(duì)Ajax較為準(zhǔn)確的解釋:(摘自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是一種技術(shù)方案,但并不是一種新技術(shù)。它依賴的是現(xiàn)有的CSS/HTML/Javascript,而其中最核心的依賴是瀏覽器提供的XMLHttpRequest對(duì)象,是這個(gè)對(duì)象使得瀏覽器可以發(fā)出HTTP請(qǐng)求與接收HTTP響應(yīng)。

所以我用一句話來(lái)總結(jié)兩者的關(guān)系:我們使用XMLHttpRequest對(duì)象來(lái)發(fā)送一個(gè)Ajax請(qǐng)求。

XMLHttpRequest的發(fā)展歷程

XMLHttpRequest一開始只是微軟瀏覽器提供的一個(gè)接口,后來(lái)各大瀏覽器紛紛效仿也提供了這個(gè)接口,再后來(lái)W3C對(duì)它進(jìn)行了標(biāo)準(zhǔn)化,提出了XMLHttpRequest標(biāo)準(zhǔn)。XMLHttpRequest標(biāo)準(zhǔn)又分為L(zhǎng)evel 1和Level 2。XMLHttpRequest Level 1主要存在以下缺點(diǎn):

受同源策略的限制,不能發(fā)送跨域請(qǐng)求;

不能發(fā)送二進(jìn)制文件(如圖片、視頻、音頻等),只能發(fā)送純文本數(shù)據(jù);

在發(fā)送和獲取數(shù)據(jù)的過程中,無(wú)法實(shí)時(shí)獲取進(jìn)度信息,只能判斷是否完成;

那么Level 2對(duì)Level 1 進(jìn)行了改進(jìn),XMLHttpRequest Level 2中新增了以下功能:

可以發(fā)送跨域請(qǐng)求,在服務(wù)端允許的情況下;

支持發(fā)送和接收二進(jìn)制數(shù)據(jù);

新增formData對(duì)象,支持發(fā)送表單數(shù)據(jù);

發(fā)送和獲取數(shù)據(jù)時(shí),可以獲取進(jìn)度信息;

可以設(shè)置請(qǐng)求的超時(shí)時(shí)間;

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

XMLHttpRequest兼容性

關(guān)于xhr的瀏覽器兼容性,大家可以直接查看“Can I use”這個(gè)網(wǎng)站提供的結(jié)果XMLHttpRequest兼容性,下面提供一個(gè)截圖。

JS XMLHttpRequest原理與使用方法深入詳解

從圖中可以看到:

IE8/IE9、Opera Mini 完全不支持xhr對(duì)象

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

部分瀏覽器不支持設(shè)置請(qǐng)求超時(shí),即無(wú)法使用xhr.timeout

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

細(xì)說(shuō)XMLHttpRequest如何使用

先來(lái)看一段使用XMLHttpRequest發(fā)送Ajax請(qǐng)求的簡(jiǎn)單示例代碼。

function sendAjax() { //構(gòu)造表單數(shù)據(jù) var formData = new FormData(); formData.append(’username’, ’johndoe’); formData.append(’id’, 123456); //創(chuàng)建xhr對(duì)象 var xhr = new XMLHttpRequest(); //設(shè)置xhr請(qǐng)求的超時(shí)時(shí)間 xhr.timeout = 3000; //設(shè)置響應(yīng)返回的數(shù)據(jù)格式 xhr.responseType = 'text'; //創(chuàng)建一個(gè) post 請(qǐng)求,采用異步 xhr.open(’POST’, ’/server’, true); //注冊(cè)相關(guān)事件回調(diào)處理函數(shù) 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) { ... }; //發(fā)送數(shù)據(jù) xhr.send(formData);}

上面是一個(gè)使用xhr發(fā)送表單數(shù)據(jù)的示例,整個(gè)流程可以參考注釋。

接下來(lái)我將站在使用者的角度,以問題的形式介紹xhr的基本使用。我對(duì)每一個(gè)問題涉及到的知識(shí)點(diǎn)都會(huì)進(jìn)行比較細(xì)致地介紹,有些知識(shí)點(diǎn)可能是你平時(shí)忽略關(guān)注的。

如何設(shè)置request header

在發(fā)送Ajax請(qǐng)求(實(shí)質(zhì)是一個(gè)HTTP請(qǐng)求)時(shí),我們可能需要設(shè)置一些請(qǐng)求頭部信息,比如content-type、connection、cookie、accept-xxx等。xhr提供了setRequestHeader來(lái)允許我們修改請(qǐng)求 header。

void setRequestHeader(DOMString header, DOMString value);

注意點(diǎn)

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

Content-Type的默認(rèn)值與具體發(fā)送的數(shù)據(jù)類型有關(guān),請(qǐng)參考本文【可以發(fā)送什么類型的數(shù)據(jù)】一節(jié);

setRequestHeader必須在open()方法之后,send()方法之前調(diào)用,否則會(huì)拋錯(cuò);

setRequestHeader可以調(diào)用多次,最終的值不會(huì)采用覆蓋override的方式,而是采用追加append的方式。下面是一個(gè)示例代碼:

var client = new XMLHttpRequest();client.open(’GET’, ’demo.cgi’);client.setRequestHeader(’X-Test’, ’one’);client.setRequestHeader(’X-Test’, ’two’);// 最終request header中'X-Test'為: one, twoclient.send();如何獲取response header

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

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

這2個(gè)方法看起來(lái)簡(jiǎn)單,但卻處處是坑兒。

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

使用getAllResponseHeaders()看到的所有response header與實(shí)際在控制臺(tái) Network 中看到的 response header 不一樣

使用getResponseHeader()獲取某個(gè) header 的值時(shí),瀏覽器拋錯(cuò)Refused to get unsafe header 'XXX'

經(jīng)過一番尋找最終在 Stack Overflow找到了答案。

原因1:W3C的 xhr 標(biāo)準(zhǔn)中做了限制,規(guī)定客戶端無(wú)法獲取 response 中的 Set-Cookie、Set-Cookie2這2個(gè)字段,無(wú)論是同域還是跨域請(qǐng)求;

原因2:W3C 的 cors 標(biāo)準(zhǔn)對(duì)于跨域請(qǐng)求也做了限制,規(guī)定對(duì)于跨域請(qǐng)求,客戶端允許獲取的response header字段只限于“simple response header”和“Access-Control-Expose-Headers” (兩個(gè)名詞的解釋見下方)。

'simple response header'包括的 header 字段有:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma;'Access-Control-Expose-Headers':首先得注意是'Access-Control-Expose-Headers'進(jìn)行跨域請(qǐng)求時(shí)響應(yīng)頭部中的一個(gè)字段,對(duì)于同域請(qǐng)求,響應(yīng)頭部是沒有這個(gè)字段的。這個(gè)字段中列舉的 header 字段就是服務(wù)器允許暴露給客戶端訪問的字段。

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

如何指定xhr.response的數(shù)據(jù)類型

有些時(shí)候我們希望xhr.response返回的就是我們想要的數(shù)據(jù)類型。比如:響應(yīng)返回的數(shù)據(jù)是純JSON字符串,但我們期望最終通過xhr.response拿到的直接就是一個(gè) js 對(duì)象,我們?cè)撛趺磳?shí)現(xiàn)呢?有2種方法可以實(shí)現(xiàn),一個(gè)是level 1就提供的overrideMimeType()方法,另一個(gè)是level 2才提供的xhr.responseType屬性。

xhr.overrideMimeType()

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

再舉一個(gè)使用場(chǎng)景,我們都知道xhr level 1不支持直接傳輸blob二進(jìn)制數(shù)據(jù),那如果真要傳輸 blob 該怎么辦呢?當(dāng)時(shí)就是利用overrideMimeType方法來(lái)解決這個(gè)問題的。

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

var xhr = new XMLHttpRequest();//向 server 端獲取一張圖片xhr.open(’GET’, ’/path/to/image.png’, true);// 這行是關(guān)鍵!//將響應(yīng)數(shù)據(jù)按照純文本格式來(lái)解析,字符集替換為用戶自己定義的字符集xhr.overrideMimeType(’text/plain; charset=x-user-defined’);xhr.onreadystatechange = function(e) { if (this.readyState == 4 && this.status == 200) { //通過 responseText 來(lái)獲取圖片文件對(duì)應(yīng)的二進(jìn)制字符串 var binStr = this.responseText; //然后自己再想方法將逐個(gè)字節(jié)還原為二進(jìn)制數(shù)據(jù) 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請(qǐng)求的是一張圖片,通過將 response 的 content-type 改為’text/plain; charset=x-user-defined’,使得 xhr 以純文本格式來(lái)解析接收到的blob 數(shù)據(jù),最終用戶通過this.responseText拿到的就是圖片文件對(duì)應(yīng)的二進(jìn)制字符串,最后再將其轉(zhuǎn)換為 blob 數(shù)據(jù)。

xhr.responseType

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

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

下面是同樣是獲取一張圖片的代碼示例,相比xhr.overrideMimeType,用xhr.response來(lái)實(shí)現(xiàn)簡(jiǎn)單得多。

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

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

如何獲取response數(shù)據(jù)

xhr提供了3個(gè)屬性來(lái)獲取請(qǐng)求返回的數(shù)據(jù),分別是:xhr.response、xhr.responseText、xhr.responseXML

xhr.response

默認(rèn)值:空字符串''

當(dāng)請(qǐng)求完成時(shí),此屬性才有正確的值

請(qǐng)求未完成時(shí),此屬性的值可能是''或者 null,具體與 xhr.responseType有關(guān):當(dāng)responseType為''或'text'時(shí),值為'';responseType為其他值時(shí),值為 null

xhr.responseText

默認(rèn)值為空字符串''

只有當(dāng) responseType 為'text'、''時(shí),xhr對(duì)象上才有此屬性,此時(shí)才能調(diào)用xhr.responseText,否則拋錯(cuò)

只有當(dāng)請(qǐng)求成功時(shí),才能拿到正確值。以下2種情況下值都為空字符串'':請(qǐng)求未完成、請(qǐng)求失敗

xhr.responseXML

默認(rèn)值為 null

只有當(dāng) responseType 為'text'、''、'document'時(shí),xhr對(duì)象上才有此屬性,此時(shí)才能調(diào)用xhr.responseXML,否則拋錯(cuò)

只有當(dāng)請(qǐng)求成功且返回?cái)?shù)據(jù)被正確解析時(shí),才能拿到正確值。以下3種情況下值都為null:請(qǐng)求未完成、請(qǐng)求失敗、請(qǐng)求成功但返回?cái)?shù)據(jù)無(wú)法被正確解析時(shí)

如何追蹤ajax請(qǐng)求的當(dāng)前狀態(tài)

在發(fā)一個(gè)ajax請(qǐng)求后,如果想追蹤請(qǐng)求當(dāng)前處于哪種狀態(tài),該怎么做呢?

用xhr.readyState這個(gè)屬性即可追蹤到。這個(gè)屬性是只讀屬性,總共有5種可能值,分別對(duì)應(yīng)xhr不同的不同階段。每次xhr.readyState的值發(fā)生變化時(shí),都會(huì)觸發(fā)xhr.onreadystatechange事件,我們可以在這個(gè)事件中進(jìn)行相關(guān)狀態(tài)判斷。

xhr.onreadystatechange = function () { switch(xhr.readyState){ case 1://OPENED //do something break; case 2://HEADERS_RECEIVED //do something break; case 3://LOADING //do something break; case 4://DONE //do something break; } 值 狀態(tài) 描述 0 UNSENT (初始狀態(tài),未打開) 此時(shí)xhr對(duì)象被成功構(gòu)造,open()方法還未被調(diào)用 1 OPENED (已打開,未發(fā)送) open()方法已被成功調(diào)用,send()方法還未被調(diào)用。注意:只有xhr處于OPENED狀態(tài),才能調(diào)用xhr.setRequestHeader()和xhr.send(),否則會(huì)報(bào)錯(cuò) 2 HEADERS_RECEIVED (已獲取響應(yīng)頭) send()方法已經(jīng)被調(diào)用, 響應(yīng)頭和響應(yīng)狀態(tài)已經(jīng)返回 3 LOADING (正在下載響應(yīng)體) 響應(yīng)體(response entity body)正在下載中,此狀態(tài)下通過xhr.response可能已經(jīng)有了響應(yīng)數(shù)據(jù) 4 DONE (整個(gè)數(shù)據(jù)傳輸過程結(jié)束) 整個(gè)數(shù)據(jù)傳輸過程結(jié)束,不管本次請(qǐng)求是成功還是失敗 如何設(shè)置請(qǐng)求的超時(shí)時(shí)間

如果請(qǐng)求過了很久還沒有成功,為了不會(huì)白白占用的網(wǎng)絡(luò)資源,我們一般會(huì)主動(dòng)終止請(qǐng)求。XMLHttpRequest提供了timeout屬性來(lái)允許設(shè)置請(qǐng)求的超時(shí)時(shí)間。

xhr.timeout

單位:milliseconds 毫秒默認(rèn)值:0,即不設(shè)置超時(shí)

很多同學(xué)都知道:從請(qǐng)求開始 算起,若超過 timeout 時(shí)間請(qǐng)求還沒有結(jié)束(包括成功/失敗),則會(huì)觸發(fā)ontimeout事件,主動(dòng)結(jié)束該請(qǐng)求。

【那么到底什么時(shí)候才算是請(qǐng)求開始 ?】——xhr.onloadstart事件觸發(fā)的時(shí)候,也就是你調(diào)用xhr.send()方法的時(shí)候。因?yàn)閤hr.open()只是創(chuàng)建了一個(gè)連接,但并沒有真正開始數(shù)據(jù)的傳輸,而xhr.send()才是真正開始了數(shù)據(jù)的傳輸過程。只有調(diào)用了xhr.send(),才會(huì)觸發(fā)xhr.onloadstart 。

【那么什么時(shí)候才算是請(qǐng)求結(jié)束 ?】—— xhr.loadend事件觸發(fā)的時(shí)候。

另外,還有2個(gè)需要注意的坑兒:

可以在 send()之后再設(shè)置此xhr.timeout,但計(jì)時(shí)起始點(diǎn)仍為調(diào)用xhr.send()方法的時(shí)刻。

當(dāng)xhr為一個(gè)sync同步請(qǐng)求時(shí),xhr.timeout必須置為0,否則會(huì)拋錯(cuò)。原因可以參考本文的【如何發(fā)一個(gè)同步請(qǐng)求】一節(jié)。

如何發(fā)一個(gè)同步請(qǐng)求

xhr默認(rèn)發(fā)的是異步請(qǐng)求,但也支持發(fā)同步請(qǐng)求(當(dāng)然實(shí)際開發(fā)中應(yīng)該盡量避免使用)。到底是異步還是同步請(qǐng)求,由xhr.open()傳入的async參數(shù)決定。

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

method: 請(qǐng)求的方式,如GET/POST/HEADER等,這個(gè)參數(shù)不區(qū)分大小寫

url: 請(qǐng)求的地址,可以是相對(duì)地址如example.php,這個(gè)相對(duì)是相對(duì)于當(dāng)前網(wǎng)頁(yè)的url路徑;也可以是絕對(duì)地址如http://www.example.com/example.php

async: 默認(rèn)值為true,即為異步請(qǐng)求,若async=false,則為同步請(qǐng)求

在我認(rèn)真研讀W3C 的 xhr 標(biāo)準(zhǔn)前,我總以為同步請(qǐng)求和異步請(qǐng)求只是阻塞和非阻塞的區(qū)別,其他什么事件觸發(fā)、參數(shù)設(shè)置應(yīng)該是一樣的,事實(shí)證明我錯(cuò)了。

W3C 的 xhr標(biāo)準(zhǔn)中關(guān)于open()方法有這樣一段說(shuō)明:

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.

從上面一段說(shuō)明可以知道,當(dāng)xhr為同步請(qǐng)求時(shí),有如下限制:

xhr.timeout必須為0

xhr.withCredentials必須為 false

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

若上面任何一個(gè)限制不滿足,都會(huì)拋錯(cuò),而對(duì)于異步請(qǐng)求,則沒有這些參數(shù)設(shè)置上的限制。

之前說(shuō)過頁(yè)面中應(yīng)該盡量避免使用sync同步請(qǐng)求,為什么呢?因?yàn)槲覀儫o(wú)法設(shè)置請(qǐng)求超時(shí)時(shí)間(xhr.timeout為0,即不限時(shí))。在不限制超時(shí)的情況下,有可能同步請(qǐng)求一直處于pending狀態(tài),服務(wù)端遲遲不返回響應(yīng),這樣整個(gè)頁(yè)面就會(huì)一直阻塞,無(wú)法響應(yīng)用戶的其他交互。

另外,標(biāo)準(zhǔn)中并沒有提及同步請(qǐng)求時(shí)事件觸發(fā)的限制,但實(shí)際開發(fā)中我確實(shí)遇到過部分應(yīng)該觸發(fā)的事件并沒有觸發(fā)的現(xiàn)象。如在 chrome中,當(dāng)xhr為同步請(qǐng)求時(shí),在xhr.readyState由2變成3時(shí),并不會(huì)觸發(fā) onreadystatechange事件,xhr.upload.onprogress和 xhr.onprogress事件也不會(huì)觸發(fā)。

如何獲取上傳、下載的進(jìn)度

在上傳或者下載比較大的文件時(shí),實(shí)時(shí)顯示當(dāng)前的上傳、下載進(jìn)度是很普遍的產(chǎn)品需求。我們可以通過onprogress事件來(lái)實(shí)時(shí)顯示進(jìn)度,默認(rèn)情況下這個(gè)事件每50ms觸發(fā)一次。需要注意的是,上傳過程和下載過程觸發(fā)的是不同對(duì)象的onprogress事件:

上傳觸發(fā)的是xhr.upload對(duì)象的 onprogress事件

下載觸發(fā)的是xhr對(duì)象的onprogress事件

xhr.onprogress = updateProgress;xhr.upload.onprogress = updateProgress;function updateProgress(event) { if (event.lengthComputable) { var completedPercent = event.loaded / event.total; } }可以發(fā)送什么類型的數(shù)據(jù)

void send(data);

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

ArrayBuffer

Blob

Document

DOMString

FormData

null

如果是 GET/HEAD請(qǐng)求,send()方法一般不傳參或傳 null。不過即使你真?zhèn)魅肓藚?shù),參數(shù)也最終被忽略,xhr.send(data)中的data會(huì)被置為 null.

xhr.send(data)中data參數(shù)的數(shù)據(jù)類型會(huì)影響請(qǐng)求頭部content-type的默認(rèn)值:

如果data是 Document 類型,同時(shí)也是HTML Document類型,則content-type默認(rèn)值為text/html;charset=UTF-8;否則為application/xml;charset=UTF-8;

如果data是 DOMString 類型,content-type默認(rèn)值為text/plain;charset=UTF-8;

如果data是 FormData 類型,content-type默認(rèn)值為multipart/form-data; boundary=[xxx]

如果data是其他類型,則不會(huì)設(shè)置content-type的默認(rèn)值

當(dāng)然這些只是content-type的默認(rèn)值,但如果用xhr.setRequestHeader()手動(dòng)設(shè)置了中content-type的值,以上默認(rèn)值就會(huì)被覆蓋。

另外需要注意的是,若在斷網(wǎng)狀態(tài)下調(diào)用xhr.send(data)方法,則會(huì)拋錯(cuò):Uncaught NetworkError: Failed to execute ’send’ on ’XMLHttpRequest’。一旦程序拋出錯(cuò)誤,如果不 catch 就無(wú)法繼續(xù)執(zhí)行后面的代碼,所以調(diào)用 xhr.send(data)方法時(shí),應(yīng)該用 try-catch捕捉錯(cuò)誤。

try{ xhr.send(data) }catch(e) { //doSomething... };xhr.withCredentials與 CORS 什么關(guān)系

我們都知道,在發(fā)同域請(qǐng)求時(shí),瀏覽器會(huì)將cookie自動(dòng)加在request header中。但大家是否遇到過這樣的場(chǎng)景:在發(fā)送跨域請(qǐng)求時(shí),cookie并沒有自動(dòng)加在request header中。

造成這個(gè)問題的原因是:在CORS標(biāo)準(zhǔn)中做了規(guī)定,默認(rèn)情況下,瀏覽器在發(fā)送跨域請(qǐng)求時(shí),不能發(fā)送任何認(rèn)證信息(credentials)如'cookies'和'HTTP authentication schemes'。除非xhr.withCredentials為true(xhr對(duì)象有一個(gè)屬性叫withCredentials,默認(rèn)值為false)。

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

另外,要特別注意一點(diǎn),一旦跨域request能夠攜帶認(rèn)證信息,server端一定不能將Access-Control-Allow-Origin設(shè)置為*,而必須設(shè)置為請(qǐng)求頁(yè)面的域名。

xhr相關(guān)事件事件分類

xhr相關(guān)事件有很多,有時(shí)記起來(lái)還挺容易混亂。但當(dāng)我了解了具體代碼實(shí)現(xiàn)后,就容易理清楚了。下面是XMLHttpRequest的部分實(shí)現(xiàn)代碼:

interface XMLHttpRequestEventTarget : EventTarget { // event handlers attribute 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 handler attribute EventHandler onreadystatechange; readonly attribute XMLHttpRequestUpload upload;};

從代碼中我們可以看出:

XMLHttpRequestEventTarget接口定義了7個(gè)事件:

onloadstart

onprogress

onabort

ontimeout

onerror

onload

onloadend

每一個(gè)XMLHttpRequest里面都有一個(gè)upload屬性,而upload是一個(gè)XMLHttpRequestUpload對(duì)象

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

onreadystatechange是XMLHttpRequest獨(dú)有的事件

所以這么一看就很清晰了:xhr一共有8個(gè)相關(guān)事件:7個(gè)XMLHttpRequestEventTarget事件+1個(gè)獨(dú)有的onreadystatechange事件;而xhr.upload只有7個(gè)XMLHttpRequestEventTarget事件。

事件觸發(fā)條件

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

事件 觸發(fā)條件 onreadystatechange 每當(dāng)xhr.readyState改變時(shí)觸發(fā);但xhr.readyState由非0值變?yōu)?時(shí)不觸發(fā)。 onloadstart 調(diào)用xhr.send()方法后立即觸發(fā),若xhr.send()未被調(diào)用則不會(huì)觸發(fā)此事件。 onprogress xhr.upload.onprogress在上傳階段(即xhr.send()之后,xhr.readystate=2之前)觸發(fā),每50ms觸發(fā)一次;xhr.onprogress在下載階段(即xhr.readystate=3時(shí))觸發(fā),每50ms觸發(fā)一次。 onload 當(dāng)請(qǐng)求成功完成時(shí)觸發(fā),此時(shí)xhr.readystate=4 onloadend 當(dāng)請(qǐng)求結(jié)束(包括請(qǐng)求成功和請(qǐng)求失敗)時(shí)觸發(fā) onabort 當(dāng)調(diào)用xhr.abort()后觸發(fā) ontimeout xhr.timeout不等于0,由請(qǐng)求開始即onloadstart開始算起,當(dāng)?shù)竭_(dá)xhr.timeout所設(shè)置時(shí)間請(qǐng)求還未結(jié)束即onloadend,則觸發(fā)此事件。 onerror 在請(qǐng)求過程中,若發(fā)生Network error則會(huì)觸發(fā)此事件(若發(fā)生Network error時(shí),上傳還沒有結(jié)束,則會(huì)先觸發(fā)xhr.upload.onerror,再觸發(fā)xhr.onerror;若發(fā)生Network error時(shí),上傳已經(jīng)結(jié)束,則只會(huì)觸發(fā)xhr.onerror)。注意,只有發(fā)生了網(wǎng)絡(luò)層級(jí)別的異常才會(huì)觸發(fā)此事件,對(duì)于應(yīng)用層級(jí)別的異常,如響應(yīng)返回的xhr.statusCode是4xx時(shí),并不屬于Network error,所以不會(huì)觸發(fā)onerror事件,而是會(huì)觸發(fā)onload事件。 事件觸發(fā)順序

當(dāng)請(qǐng)求一切正常時(shí),相關(guān)的事件觸發(fā)順序如下:

觸發(fā)xhr.onreadystatechange(之后每次readyState變化時(shí),都會(huì)觸發(fā)一次)

觸發(fā)xhr.onloadstart //上傳階段開始:

觸發(fā)xhr.upload.onloadstart

觸發(fā)xhr.upload.onprogress

觸發(fā)xhr.upload.onload

觸發(fā)xhr.upload.onloadend //上傳結(jié)束,下載階段開始:

觸發(fā)xhr.onprogress

觸發(fā)xhr.onload

觸發(fā)xhr.onloadend

發(fā)生abort/timeout/error異常的處理

在請(qǐng)求的過程中,有可能發(fā)生 abort/timeout/error這3種異常。那么一旦發(fā)生這些異常,xhr后續(xù)會(huì)進(jìn)行哪些處理呢?后續(xù)處理如下:

一旦發(fā)生abort或timeout或error異常,先立即中止當(dāng)前請(qǐng)求

將 readystate 置為4,并觸發(fā) xhr.onreadystatechange事件

如果上傳階段還沒有結(jié)束,則依次觸發(fā)以下事件:

xhr.upload.onprogress

xhr.upload.[onabort或ontimeout或onerror]

xhr.upload.onloadend

觸發(fā) xhr.onprogress事件

觸發(fā) xhr.[onabort或ontimeout或onerror]事件

觸發(fā)xhr.onloadend 事件

在哪個(gè)xhr事件中注冊(cè)成功回調(diào)?

從上面介紹的事件中,可以知道若xhr請(qǐng)求成功,就會(huì)觸發(fā)xhr.onreadystatechange和xhr.onload兩個(gè)事件。 那么我們到底要將成功回調(diào)注冊(cè)在哪個(gè)事件中呢?我傾向于 xhr.onload事件,因?yàn)閤hr.onreadystatechange是每次xhr.readyState變化時(shí)都會(huì)觸發(fā),而不是xhr.readyState=4時(shí)才觸發(fā)。

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

上面的示例代碼是很常見的寫法:先判斷http狀態(tài)碼是否是200,如果是,則認(rèn)為請(qǐng)求是成功的,接著執(zhí)行成功回調(diào)。這樣的判斷是有坑兒的,比如當(dāng)返回的http狀態(tài)碼不是200,而是201時(shí),請(qǐng)求雖然也是成功的,但并沒有執(zhí)行成功回調(diào)邏輯。所以更靠譜的判斷方法應(yīng)該是:當(dāng)http狀態(tài)碼為2xx或304時(shí)才認(rèn)為成功。

xhr.onload = function () { //如果請(qǐng)求成功 if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ //do successCallback } }結(jié)語(yǔ)

終于寫完了......看完那一篇長(zhǎng)長(zhǎng)的W3C的xhr 標(biāo)準(zhǔn),我眼睛都花了......希望這篇總結(jié)能幫助剛開始接觸XMLHttpRequest的你。

最后給點(diǎn)擴(kuò)展學(xué)習(xí)資料,如果你:

想真正搞懂XMLHttpRequest,最靠譜的方法還是看 W3C的xhr 標(biāo)準(zhǔn);

想結(jié)合代碼學(xué)習(xí)如何用XMLHttpRequest發(fā)各種類型的數(shù)據(jù),可以參考html5rocks上的這篇文章

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

想了解XMLHttpRequest 的發(fā)展歷程,可以參考阮老師的文章;

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

想了解跨域請(qǐng)求,則可以參考W3C的 cors 標(biāo)準(zhǔn);

想了解http協(xié)議,則可以參考HTTP Tutorial;

更多關(guān)于ajax相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《jquery中Ajax用法總結(jié)》、《JavaScript中ajax操作技巧總結(jié)》、《PHP+ajax技巧與應(yīng)用小結(jié)》及《asp.net ajax技巧總結(jié)專題》

希望本文所述對(duì)大家ajax程序設(shè)計(jì)有所幫助。

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 天天天天天天天天干 | 精品小视频在线观看 | 99热在线免费 | 福利在线一区二区 | 国产这里只有精品 | 国产又粗又黄又爽又硬的免费视频 | 日韩福利 | 99久在线观看 | 国产高清在线观看视频 | 欧美一区二区三区喷汁尤物 | 午夜在线国产 | 大乳村妇的性需求 | 激情婷婷网 | 欧美 国产精品 | 一区二区三区福利视频 | 国产精品久久人 | 一级视频毛片 | 北条麻妃一区二区三区中文字幕 | 精品无码国产av一区二区 | 日韩a视频 | 亚洲国产精品成人综合久久久久久久 | 国产一区二区三区久久久久久久久 | 日韩欧美精品在线视频 | 日批视频在线 | 91亚洲网站| 日韩第1页 | 亚洲激情在线视频 | 国内精品伊人久久久久7777 | 国产高中女学生第一次 | 国产乱码精品一区二区三区四川人 | 91精品国产欧美一区二区 | 欧美精品第三页 | 日老女人视频 | www天堂av| 高清日韩欧美 | 风韵丰满熟妇啪啪区老老熟妇 | 欧美日韩国产三级 | 一本色道综合久久欧美日韩精品 | 成人精品一区二区三区 | 午夜伦理久久 | 91在线视频在线观看 | 欧美精品一区在线观看 | 日本精品视频一区二区三区四区 | 欧美麻豆 | 欧美一区二区三区不卡视频 | 狠狠鲁影院 | 色呦呦在线播放 | 中文字幕蜜臀 | 亚洲日本va中文字幕久久 | 久久久一本精品99久久精品66 | cao在线 | 日本高清www免费视频 | 亚洲高清国产拍精品网络战 | 日韩激情一区二区三区 | 亚洲伊人色综合网站小说 | 成人美女视频在线观看 | 一级女人裸体舞毛片 | 综合天天色 | 久久久久无码精品国产app | 2021国产精品自在自线 | 东北女人av | 一区二区三区免费看 | 国产91在线 | 中文 | 91麻豆影视 | 国产精品一区二区三区不卡 | 伊人久久大香线蕉av一区 | 国产精品日韩欧美一区二区 | 日韩欧美中文字幕一区 | 日韩中文字幕免费观看 | 欧美黄色xxx| 无码高潮爽到爆的喷水视频 | 久久综合激的五月天 | 国产一区二区三区四区五区入口 | 免费纯肉3d动漫无码网站 | 超h高h污肉校园np在线观看 | 国产免费一区二区三区最新6 | 一级性爱视频 | 国产伦精品一区二区三区四区免费 | 18禁网站免费无遮挡无码中文 | 成人在线国产视频 | av十大美巨乳 | 久久一区二区三区精华液使用 | www成人在线 | 波多野结av衣东京热无码专区 | 国产精品日韩欧美一区二区三区 | 99国产精品久久久久久久 | 国产又黄又猛视频 | 国产高清黄色 | 菲律宾黄色片 | 青娱乐99 | 五月婷婷俺也去 | 日韩精品h| 欧美午夜刺激影院 | 成人免费一级片 | 外国黄色网址 | 国产精品国产三级国产aⅴ中文 | 久久精品国产一区二区三区肥胖 | 国产午夜精品一区二区三区视频 | 夜夜草天天草 | 337p日本欧洲亚大胆精80 | 亚洲精华国产 | 日韩视频一区二区三区在线播放免费观看 | 免费麻豆视频 | 少妇做爰免费视频网站www | 欧美乱妇高清无乱码 | 无遮无挡三级动态图 | 国产精品免费麻豆入口 | 欧美日韩在线一区二区 | 日韩一区精品视频一区二区 | 越南少妇做受xxx片 越南性xxxx精品hd | 亚洲色图av在线 | 九色视频偷拍少妇的秘密 | 一区二区黄色 | 真实强推精品半推半就 | 亚色av| 成人做爰www网站视频 | 一区二区少妇 | 亚洲视频区 | 国产精品99久久 | 91麻豆精品国产 | 天堂va欧美va亚洲va老司机 | 欧美日韩在线一区二区三区 | 丁香激情五月少妇 | 亚洲色图网站 | 五月久久久综合一区二区小说 | 欧美a在线播放 | 美女少妇av | h无码动漫在线观看 | 小视频在线观看 | 人人草人人看 | 97精品伊人久久久大香线蕉 | 久草视频精品 | 亚洲国产精品激情综合图片 | 一色桃子656中文字幕 | 亚洲精品网站在线 | 国产无套粉嫩白浆内精品 | 日韩欧美亚洲成人 | 国产av一区二区三区天堂综合网 | 玩弄少妇人妻中文字幕 | 午夜肉伦伦 | 风韵丰满熟妇啪啪区老老熟妇 | 妖精色av无码国产在线看 | 色翁荡熄又大又硬又粗又视频图片 | 亚洲a∨无码男人的天堂 | 亚洲乳大丰满中文字幕 | 午夜爱精品免费视频一区二区 | 日本一区高清 | 丰满人妻熟妇乱偷人无码 | 精品一区二区在线观看视频 | 91看片就是不一样 | 日本人裸体做爰视频 | 中文字幕+乱码+中文乱码www | 欧美日韩中文字幕视频 | 综合影院 | 奇米99| 久久伊人热 | 亚洲熟妇无码一区二区三区导航 | 欧美亚洲黄色 | 国产尤物精品视频 | 祝英台艳史高h(np)小说全文 | 久久久999成人| 久久精品亚洲a | jizzjizz国产精品喷水 | 图片区亚洲色图 | 8888四色奇米在线观看 | 国产一区二区三区在线电影 | 亚洲无吗在线 | 人人揉人人 | 日韩国产中文字幕 | 国产成人无码a区视频在线观看 | 日日躁夜夜躁狠狠躁aⅴ蜜 日日躁夜夜躁狠狠躁超爽2001 | 国产日韩欧美在线观看 | 亚洲va韩国va欧美va精四季 | 久久zyz资源站无码中文动漫 | 欧美一区二区三区四区五区六区 | 国产真实精品久久二三区 | 另类小说五月天 | 日韩在线视频观看 | 免费看男女做爰爽爽视频 | 国产精品美女毛片真酒店 | 午夜亚洲一区 | 亚洲熟妇无码爱v在线观看 又色又爽又黄18禁美女裸身无遮挡 | 国产精品v日韩精品v在线观看 | 午夜久| 欧美xxxx黑人又粗又长 | 国产精品9999久久久久仙踪林 | 国产极品美女高潮抽搐免费网站 | 日韩欧美一区二区三区视频 | 中文在线第一页 | 91麻豆免费视频 | 精品久久久久久久久久久国产字幕 | 久久成人人人人精品欧 | 99精品在线观看 | 亚洲久悠悠色悠在线播放 | 久久婷婷五月综合色国产 | 1000部夫妻午夜免费 | 91啦中文 | 99久久夜色精品国产亚洲1000部 | 午夜精品久久久久久久白皮肤 | 日韩a毛片| 中文字幕第8页 | 黄色一级视频网站 | 日韩欧美国产片 | 91久久北条麻妃一区二区三区 | 日韩精品成人无码专区免费 | 成熟亚洲日本毛茸茸凸凹 | 免费簧片在线观看 | 亚洲狠狠爱一区二区三区 | 一卡二卡三卡视频 | 亚洲va国产日韩欧美精品色婷婷 | 最近中文2019字幕第二页 | 永久免费看片女女 | 亚洲精品国产精品自产a区红杏吧 | 久热re这里精品视频在线6 | 99精品国产一区二区三区2021 | 中文字幕一区在线观看视频 | 国产一级片免费观看 | 91看片在线看 | av日韩精品 | 亚洲乱码国产一区三区 | 精品无码一区二区三区不卡 | 亚洲免费区 | 国产精品无码av一区二区三区 | 午夜夜伦鲁鲁片六度影院 | 一区二区三区波多野结衣 | 中文字幕乱码亚洲精品一区 | 最新无码a∨在线观看 | 超碰福利在线观看 | 久中文字幕 | 欧美一级一区二区三区 | 中文字幕av高清片 | 福利视频一二三区 | 精品在线视频一区二区三区 | 国产精品久久久久永久免费 | 国产精品三级赵丽颖 | √8天堂资源地址中文在线 √天堂 | 色婷婷综合久色aⅴ五区最新 | www色偷偷com| 人人射影院 | 欧美黑人xxxx高潮猛交 | 国产在线观看码高清视频 | av在线播放一区二区三区 | 多毛的亚洲人毛茸茸 | 中文字幕+乱码+中文字幕一区 | 国产无线乱码一区二三区 | 中文字幕亚洲区 | 久久精品视频5 | 国产亚洲三级 | 久久精品一区二区三 | 91蜜桃婷婷狠狠久久综合9色 | 国精一二二产品无人区免费应用 | 国产一区二区三区精品在线 | 99久久精品费精品国产风间由美 | 一个人看的www日本高清视频 | 国产97自拍 | 97成人免费| 在线a毛片| 精品国产一区二区三区四区五区 | 伊人亚洲天堂 | 成人在线中文字幕 | 国产精品视频一区二区免费不卡 | 国产大学生呻吟对白精彩在线 | 免费久久视频 | 91福利影院 | 欧美激情国产精品日韩 | 国产色欲av一区二区三区 | 丰满少妇高潮在线播放不卡 | 手机看片99 | www.887色视频免费 | 香蕉97超级碰碰碰免费公开 | 久久人人爽人人爽人人片 | 久色成人网 | 超碰成人97 | av网站在线看 | 亚洲精品视频在线观看免费 | 晨勃顶到尿h1v1 | 中文字幕无人区二 | 久久成人国产精品入口 | 精品成在人线av无码免费看 | 一个人在线免费观看www | 美女黄免费 | 精品国产鲁一鲁一区二区张丽 | 欧美黑人又粗又大的性格特点 | 欧美一极片 | 中文字幕av无码一区二区三区电影 | 男女搞网站 | 最新2020无码中文字幕在线视频 | 午夜影院在线免费观看视频 | 国产精品www色诱视频 | 欧美久久久久 | 国产丝袜视频在线 | 中文无码精品一区二区三区 | 无码人妻品一区二区三区精99 | 日韩av色图 | 成人在线不卡 | 久久99精品一区二区蜜桃臀 | 精品国自产在线观看 | 黄色一级片视频 | 国产乱淫av片免费观看 | 精品无码av无码免费专区 | 国语久久 | 黄色草逼视频 | 少妇黄色片 | 日韩成人av网站 | 激情国产av做激情国产爱 | av2014天堂| 成人高清视频免费观看 | 一级特黄少妇高清毛片 | 久久综合av色老头免费观看 | 亚洲视频一区二区 | 成人精品网 | 亚洲乱码av | 国产天码青椒老色批青椒影视 | 日韩成人短视频 | 91丨九色丨黑人外教 | 欧美日韩视频 | 久国产精品韩国三级视频 | 欧美图片在线观看 | 丰满少妇久久久久久久 | 91成人看片免费版 | 亚洲激情在线播放 | 强videoshd酒醉 | 熟妇高潮一区二区三区 | 国产手机在线精品 | 国产伦精品| 亚洲一级一级一级 | 热久久国产精品 | 放荡艳妇的疯狂呻吟中文视频 | 国产日本一区二区 | 91九色成人 | 欧美射射射 | 91亚洲网站 | 天堂网在线最新版www中文网 | 好吊日精品视频 | 人人爽人人爽人人片 | av黄色在线播放 | a级毛片网 | 国产一性一交一伦一a片 | 99久久国产视频 | 欧美性猛交乱大交xxxxx | 国产黄色片免费看 | 综合99| 国产欧美日韩va另类在线播放 | 少妇高潮毛片高清免费播放 | 成人毛片基地 | 美女张开腿黄网站免费下载 | 长河落日电视连续剧免费观看 | 亚洲娇小业余黑人巨大汇总 | 北条麻妃一区二区三区中文字幕 | 国产精品亚洲成在人线 | 国产一区二区久久久 | 欧美大浪妇猛交饥渴大叫 | 亚洲一区二区福利视频 | 国产欧美日韩中文久久 | 免费观看污视频 | 天海翼一区二区三区高清在线观看 | 日本一级一片免费视频 | 奇米影视亚洲 | 欧美色图狠狠干 | 久久免费黄色网址 | 中文字幕无码视频手机免费看 | 欧美黄色精品 | 日韩欧美一级片 | av在线亚洲欧洲日产一区二区 | 外国黄色网址 | 成人片黄网站色大片免费观看 | 久久两性视频 | 久久av网 | 亚洲蜜臀av | 国产人妖cd在线看网站 | 亚洲日韩av一区二区三区四区 | 国内激情自拍 | 中文日韩一区二区 | 国产欧美一区二区精品秋霞影院 | 亚洲天堂av线 | 翁虹三级做爰在线播放 | 中文字幕在线观看网站 | 成年无码av片在线狼人 | 欧美亚洲国产精品久久 | 亚洲一级片| 69久久99精品久久久久婷婷 | 欧美日韩一级黄色片 | 在线不卡的av| 国产亚洲精品久久久网站好莱 | av无码av天天av天天爽 | 午夜av一区二区 | 99国产精品国产免费观看 | 亚洲精品久久久久久久久久 | 国产精品高潮呻吟久久av无 | 97久久精品午夜一区二区 | 欧美一区二区三区久久综合 | 精精国产xxxx视频在线 | 国产精强码久久久久影片at | 黄色激情av | 人善交另类亚洲重口另类 | www色中色| 色天天综合网 | 人人妻人人超人人 | 人人爱人人射 | 成人天堂 | 欧洲欧美人成视频在线 | 欧美日韩精品一区二区三区蜜桃 | 免费不卡的av | 91九色蝌蚪porny | 亚洲乱亚洲乱妇无码 | 成人精品在线 | 亚洲综合影视 | 久草福利资源在线 | 久久伊人一区 | 国产精品入口麻豆九色 | 国产第4页| 国产精品国产三级国产在线观什 | 精品一区二区三区四区视频 | 草草影院在线免费观看 | 91福利社在线观看 | 亚洲国产三级在线观看 | 无遮挡啪啪摇乳动态图 | 久久成人激情 | 国产精品久久久久一区二区三区 | 国产亚洲精品久久久久蜜臀 | 欧美交a欧美精品喷水 | 黑人粗一硬一长一进一爽一a级 | 精品无码av一区二区三区 | 日韩成人无码一区二区三区 | 极品美女穴 | 日韩av色图 | 久久亚洲视频 | 国产成人精品亚洲777人妖 | 免费国产91| 亚洲爱情岛论坛永久 | 激情五月综合网 | 国产欧美久久一区二区 | 青青草免费在线 | av中文字幕在线免费观看 | 中文字幕在线网址88第一页 | 日本特级a一片免费观看 | 久久亚洲精品中文字幕 | 国产精品人妻熟女毛片av久 | 久久亚洲精品中文字幕无男同 | 亚洲人成一区 | 国产精品美女www爽爽爽视频 | 亚洲欧美v国产蜜芽tv | 精品伦一区二区三区免费视频 | 毛片入口 | 国产成人久久精品亚洲 | 国产女人18毛片18精品 | 嫩呦国产一区二区三区av | 欧美日韩一级特黄 | 四虎在线精品 | 一本到加勒比系列在线 | 色欲久久久天天天综合网 | 成人免费av在线 | 久久接色 | 粉嫩欧美一区二区三区高清影视 | 噼里啪啦免费高清看 | 国产露脸ⅹxxxⅹ高清hd | 国产午夜精品一区理论片飘花 | 99国产精品久久久久久久日本竹 | 日韩久久久久久 | 吃奶揉捏奶头高潮视频在线观看 | 精品人妻无码一区二区三区换脸 | 成人久久18免费网站图片 | 色老大视频 | 性欧美极品另类 | 欧美一区二区喷水白浆视频 | 天堂在线中文 | 亚洲6080yy久久无码产自国产 | 狠狠干天天爱 | 日韩欧美在线观看一区二区三区 | 日韩在线一区二区三区影视 | 懂色av一区二区三区四区 | 天天射天天日本一道 | 人人澡人人妻人人爽人人蜜桃 | 成年男人裸j网站 | 亚洲欧美日本一区 | 男人天堂视频网站 | 国产综合区 | 久草黄色网 | 国产精品人妖 | 午夜福利不卡在线视频 | jav成人av免费播放 | www.国产视频 | 成人激情av | 日韩在线一区视频 | 成人免费毛片网站 | 欧美成人综合 | 波多野结衣视频播放 | 美女久久久久久久 | 我爱avav色aⅴ爱avav | 黄色无遮挡网站 | 久久精品国产一区 | 国产精品伦一区二区三级视频 | 国产伦子伦视频在线观看 | 亚洲午夜视频在线观看 | 51色视频 | 综合激情婷婷 | 色羞羞| 欧美高h| 国产精品第1页 | 中文字幕在线无码一区二区三区 | 国产真实交换配乱淫视频 | 亚洲欧美日韩国产成人精品影院 | www.久久av.com| 成人女同av免费观看 | 国产亚洲精品久久久久久久软件 | 国产性猛交普通话对白 | 青青草视频在线看 | 国产一区二区视频免费 | 国自产拍偷拍精品 | 热热99| 98堂 最新网名 | 国产九色在线 | www香蕉 | 人人妻人人澡人人爽人人精品av | 亚洲一区二区三区四区五区xx | 国产一级做a爰片久久毛片99 | 一级国产航空美女毛片内谢 | 我要干成人网 | 97成人在线观看 | 得得啪在线 | 国产在线视频导航 | 国产在线网 | 99蜜桃臀久久久欧美精品网站 | 蜜桃视频在线观看污 | 天堂在线日本 | 第五色婷婷 | 日本一区二区不卡在线 | 日日躁夜夜躁狠狠躁 | 国产精品美女www爽爽爽软件 | 黄色三级免费网站 | 欧美一区二区三区成人久久片 | 亚洲精品wwww | 人妖和人妖互交性xxxx视频 | 深夜福利在线播放 | 中文字幕在线观看免费 | 久久aⅴ国产紧身牛仔裤 | 亚洲青草 | 免费黄色资源 | 久久婷婷久久 | 久久久国产精品一区二区三区 | 97av免费视频| 欧美日本另类 | 欧美中文网 | 国产亚洲精品久久久久久 | 国产精品乱子乱xxxx | 亚洲欧美在线免费观看 | 亚洲午夜精品久久久久久人妖 | 欧洲精品免费一区二区三区 | 精品视频麻豆入口 | www.亚洲黄色 | 国产精品91在线观看 | 那里有黄色网址 | 国内精品久久久久影院优 | 日本人dh亚洲人ⅹxx | 国产原创视频在线观看 | 久久99国产综合精品免费 | 亚洲天堂福利视频 | 女同重口另类在线观看 | 实拍男女野外做爰视频 | 人人人射| 99精品全国免费观看视频 | а√中文在线资源库 | 亚洲精品乱码久久久久久蜜桃欧美 | 欧美xxxxx少妇| 久草老司机 | 欧美黄色成人 | 老熟妇性老熟妇性色 | 五月婷婷一区二区 | 欧美午夜精品久久久久 | 少妇影院在线观看 | 亚洲一区二区三区四区五区乱码 | 亚洲欧美日本国产高清 | 另类天堂av| 黄色网址在线免费看 | 性色av极品无码专区亚洲 | 欧美日韩亚洲中文字幕二区 | 屁屁国产第一页草草影院 | 日本色一区 | 麻豆一区二区99久久久久 | 欧美另类交在线观看 | 国产成人亚洲在线观看 | 国产伦精品一区二区三区视频金莲 | 国产亚洲精品自在久久 | 国产东北女人做受av | 黄色aaa视频| 日本老太做爰xxxx | 天天摸天天干天天操 | 久久国产精品99久久久久 | 九九九热精品 | 粉嫩一区二区三区四区公司1 | 乱子伦一区二区 | 日韩视频网 | 色综合久久综合欧美综合网 | 国产精品久久欧美久久一区 | 国产精品久久久久不卡 | 激情综合五月婷婷 | 三级福利片 | 国产精品一区二区福利视频 | 亚洲欧美日韩精品在线观看 | 国产乱人伦精品一区二区 | 黄色网久久 | 日日摸夜夜添夜夜添欧美毛片小说 | 极品粉嫩嫩模大尺度无码视频 | 狠狠色狠狠色综合网 | 狠狠操天天操夜夜操 | 国产精品婷婷久久爽一下 | 青草国产精品久久久久久 | 久久er热在这里只有精品66 | 韩国av三级 | 亚洲高清毛片一区二区 | 老头把我添高潮了a片 | 国产三级做人爱c视频 | 欧美性猛交 xxxx | 天天鲁一鲁摸一摸爽一爽 | 69日本xxxxxxxxx30|