欧美三区四区_av先锋影音资源站_亚洲第一论坛sis_影音先锋2020色资源网_亚洲精品社区_在线免费观看av网站_国产一区二区伦理_亚洲欧美视频一区二区_99视频精品全部免费在线_精精国产xxxx视频在线

談Ajax 中的高級(jí)請(qǐng)求和響應(yīng)_AJAX教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:XMLHTTP組件相關(guān)技術(shù)資料
一、數(shù)據(jù)庫遠(yuǎn)程管理技術(shù) 基于互聯(lián)網(wǎng)的廣域網(wǎng)現(xiàn)代應(yīng)用中的一個(gè)重要環(huán)節(jié)是數(shù)據(jù)庫遠(yuǎn)程監(jiān)控。首先簡單回顧一下互聯(lián)網(wǎng)上的數(shù)據(jù)庫遠(yuǎn)程管理技術(shù)的發(fā)展過程和方式: 早期通過編寫CGI-BIN程序模塊進(jìn)行數(shù)據(jù)庫遠(yuǎn)程管理。但CGI-BIN的運(yùn)行速度慢,維護(hù)很不方便,現(xiàn)在已經(jīng)

對(duì)于很多 Web 開發(fā)人員來說,只需要生成簡單的請(qǐng)求并接收簡單的響應(yīng)即可;但是對(duì)于希望掌握 Ajax 的開發(fā)人員來說,必須要全面理解 HTTP 狀態(tài)代碼、就緒狀態(tài)和 XMLHttpRequest 對(duì)象。在本文中,Brett McLaughlin 將向您介紹各種狀態(tài)代碼,并展示瀏覽器如何對(duì)其進(jìn)行處理,本文還給出了在 Ajax 中使用的比較少見的 HTTP 請(qǐng)求。在本文中,我將在上一篇文章的基礎(chǔ)上重點(diǎn)介紹這個(gè)請(qǐng)求對(duì)象的 3 個(gè)關(guān)鍵部分的內(nèi)容:

·HTTP 就緒狀態(tài)
·HTTP 狀態(tài)代碼
·可以生成的請(qǐng)求類型

這三部分內(nèi)容都是在構(gòu)造一個(gè)請(qǐng)求時(shí)所要考慮的因素;但是介紹這些主題的內(nèi)容太少了。然而,如果您不僅僅是想了解 Ajax 編程的常識(shí),而是希望了解更多內(nèi)容,就需要熟悉就緒狀態(tài)、狀態(tài)代碼和請(qǐng)求本身的內(nèi)容。當(dāng)應(yīng)用程序出現(xiàn)問題時(shí) —— 這種問題總是存在 —— 那么如果能夠正確理解就緒狀態(tài)、如何生成一個(gè) HEAD 請(qǐng)求或者 400 的狀態(tài)代碼的確切含義,就可以在 5 分鐘內(nèi)調(diào)試出問題,而不是在各種挫折和困惑中度過 5 個(gè)小時(shí)。下面讓我們首先來看一下 HTTP 就緒狀態(tài)。

深入了解 HTTP 就緒狀態(tài)

您應(yīng)該還記得在上一篇文章中 XMLHttpRequest 對(duì)象有一個(gè)名為 readyState 的屬性。這個(gè)屬性確保服務(wù)器已經(jīng)完成了一個(gè)請(qǐng)求,通常會(huì)使用一個(gè)回調(diào)函數(shù)從服務(wù)器中讀出數(shù)據(jù)來更新 Web 表單或頁面的內(nèi)容。清單 1 給出了一個(gè)簡單的例子(這也是本系列的上一篇文章中的一個(gè)例子 —— 請(qǐng)參見 參考資料)。

 

XMLHttpRequest 或 XMLHttp:換名玫瑰

Microsoft™ 和 Internet Explorer 使用了一個(gè)名為 XMLHttp 的對(duì)象,而不是 XMLHttpRequest 對(duì)象,而 Mozilla、Opera、Safari 和 大部分非 Microsoft 瀏覽器都使用的是后者。為了簡單性起見,我將這兩個(gè)對(duì)象都簡單地稱為 XMLHttpRequest。這既符合我們?cè)?Web 上看到的情況,又符合 Microsoft 在 Internet Explorer 7.0 中使用 XMLHttpRequest 作為請(qǐng)求對(duì)象的意圖。(有關(guān)這個(gè)問題的更多內(nèi)容,請(qǐng)參見 第 2 部分。)

清單 1. 在回調(diào)函數(shù)中處理服務(wù)器的響應(yīng)

function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
} else
alert("status is " + request.status);
}
}

這顯然是就緒狀態(tài)最常見(也是最簡單)的用法。正如您從數(shù)字 "4" 中可以看出的一樣,還有其他幾個(gè)就緒狀態(tài)(您在上一篇文章中也看到過這個(gè)清單 —— 請(qǐng)參見 參考資料):

·0:請(qǐng)求未初始化(還沒有調(diào)用 open())。
·1:請(qǐng)求已經(jīng)建立,但是還沒有發(fā)送(還沒有調(diào)用 send())。
·2:請(qǐng)求已發(fā)送,正在處理中(通常現(xiàn)在可以從響應(yīng)中獲取內(nèi)容頭)。
·3:請(qǐng)求在處理中;通常響應(yīng)中已有部分?jǐn)?shù)據(jù)可用了,但是服務(wù)器還沒有完成響應(yīng)的生成。
·4:響應(yīng)已完成;您可以獲取并使用服務(wù)器的響應(yīng)了。

如果您希望不僅僅是了解 Ajax 編程的基本知識(shí),那么就不但需要知道這些狀態(tài),了解這些狀態(tài)是何時(shí)出現(xiàn)的,以及如何來使用這些狀態(tài)。首先,您需要學(xué)習(xí)在每種就緒狀態(tài)下可能碰到的是哪種請(qǐng)求狀態(tài)。不幸的是,這一點(diǎn)并不直觀,而且會(huì)涉及幾種特殊的情況。

隱秘就緒狀態(tài)

第一種就緒狀態(tài)的特點(diǎn)是 readyState 屬性為 0(readyState == 0),表示未初始化狀態(tài)。一旦對(duì)請(qǐng)求對(duì)象調(diào)用 open() 之后,這個(gè)屬性就被設(shè)置為 1。由于您通常都是在一對(duì)請(qǐng)求進(jìn)行初始化之后就立即調(diào)用 open(),因此很少會(huì)看到 readyState == 0 的狀態(tài)。另外,未初始化的就緒狀態(tài)在實(shí)際的應(yīng)用程序中是沒有真正的用處的。

不過為了滿足我們的興趣,請(qǐng)參見 清單 2 的內(nèi)容,其中顯示了如何在 readyState 被設(shè)置為 0 時(shí)來獲取這種就緒狀態(tài)。

清單 2. 獲取 0 就緒狀態(tài)

 

function getSalesData() {
// Create a request object
createRequest();
alert("Ready state is: " + request.readyState);

// Setup (initialize) the request
var url = "/boards/servlet/UpdateBoardSales";
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}

在這個(gè)簡單的例子中,getSalesData() 是 Web 頁面調(diào)用來啟動(dòng)請(qǐng)求(例如點(diǎn)擊一個(gè)按鈕時(shí))所使用的函數(shù)。注意您必須在調(diào)用 open()之前 來查看就緒狀態(tài)。圖 1 給出了運(yùn)行這個(gè)應(yīng)用程序的結(jié)果。

圖 1. 就緒狀態(tài) 0

顯然,這并不能為您帶來多少好處;需要確保 尚未 調(diào)用 open() 函數(shù)的情況很少。在大部分 Ajax 編程的真實(shí)情況中,這種就緒狀態(tài)的唯一用法就是使用相同的 XMLHttpRequest 對(duì)象在多個(gè)函數(shù)之間生成多個(gè)請(qǐng)求。在這種(不常見的)情況中,您可能會(huì)在生成新請(qǐng)求之前希望確保請(qǐng)求對(duì)象是處于未初始化狀態(tài)(readyState == 0)。這實(shí)際上是要確保另外一個(gè)函數(shù)沒有同時(shí)使用這個(gè)對(duì)象。

查看正在處理的請(qǐng)求的就緒狀態(tài)

除了 0 就緒狀態(tài)之外,請(qǐng)求對(duì)象還需要依次經(jīng)歷典型的請(qǐng)求和響應(yīng)的其他幾種就緒狀態(tài),最后才以就緒狀態(tài) 4 的形式結(jié)束。這就是為什么您在大部分回調(diào)函數(shù)中都可以看到 if (request.readyState == 4) 這行代碼;它確保服務(wù)器已經(jīng)完成對(duì)請(qǐng)求的處理,現(xiàn)在可以安全地更新 Web 頁面或根據(jù)從服務(wù)器返回來的數(shù)據(jù)來進(jìn)行操作了。

要查看這種狀態(tài)發(fā)生的過程非常簡單。如果就緒狀態(tài)為 4,我們不僅要運(yùn)行回調(diào)函數(shù)中的代碼,而且還要在每次調(diào)用回調(diào)函數(shù)時(shí)都輸出就緒狀態(tài)。 清單 3 給出了一個(gè)實(shí)現(xiàn)這種功能的例子。

當(dāng) 0 等于 4 時(shí)

在多個(gè) JavaScript 函數(shù)都使用相同的請(qǐng)求對(duì)象時(shí),您需要檢查就緒狀態(tài) 0 來確保這個(gè)請(qǐng)求對(duì)象沒有正在使用,這種機(jī)制會(huì)產(chǎn)生問題。由于 readyState == 4 表示一個(gè)已完成的請(qǐng)求,因此您經(jīng)常會(huì)發(fā)現(xiàn)那些目前沒在使用的處于就緒狀態(tài)的請(qǐng)求對(duì)象仍然被設(shè)置成了 4 —— 這是因?yàn)閺姆⻊?wù)器返回來的數(shù)據(jù)已經(jīng)使用過了,但是從它們被設(shè)置為就緒狀態(tài)之后就沒有進(jìn)行任何變化。有一個(gè)函數(shù) abort() 會(huì)重新設(shè)置請(qǐng)求對(duì)象,但是這個(gè)函數(shù)卻不是真正為了這個(gè)目的而使用的。如果您 必須 使用多個(gè)函數(shù),最好是為每個(gè)函數(shù)都創(chuàng)建并使用一個(gè)函數(shù),而不是在多個(gè)函數(shù)之間共享相同的對(duì)象。

清單 3. 查看就緒狀態(tài)

function updatePage() {
// Output the current ready state
alert("updatePage() called with ready state of " + request.readyState);
}

如果您不確定如何運(yùn)行這個(gè)函數(shù),就需要?jiǎng)?chuàng)建一個(gè)函數(shù),然后在 Web 頁面中調(diào)用這個(gè)函數(shù),并讓它向服務(wù)器端的組件發(fā)送一個(gè)請(qǐng)求(例如 清單 2 給出的函數(shù),或本系列文章的第 1 部分和第 2 部分中給出的例子)。確保在建立請(qǐng)求時(shí),將回調(diào)函數(shù)設(shè)置為 updatePage();要實(shí)現(xiàn)這種設(shè)置,可以將請(qǐng)求對(duì)象的 onreadystatechange 屬性設(shè)置為 updatePage()。

這段代碼就是 onreadystatechange 意義的一個(gè)確切展示 —— 每次請(qǐng)求的就緒狀態(tài)發(fā)生變化時(shí),就調(diào)用 updatePage(),然后我們就可以看到一個(gè)警告了。圖 2 給出了一個(gè)調(diào)用這個(gè)函數(shù)的例子,其中就緒狀態(tài)為 1。

圖 2. 就緒狀態(tài) 1

您可以自己嘗試運(yùn)行這段代碼。將其放入 Web 頁面中,然后激活事件處理程序(單擊按鈕,在域之間按 tab 鍵切換焦點(diǎn),或者使用設(shè)置的任何方法來觸發(fā)請(qǐng)求)。這個(gè)回調(diào)函數(shù)會(huì)運(yùn)行多次 —— 每次就緒狀態(tài)都會(huì)改變 —— 您可以看到每個(gè)就緒狀態(tài)的警告。這是跟蹤請(qǐng)求所經(jīng)歷的各個(gè)階段的最好方法。

瀏覽器的不一致性

在對(duì)這個(gè)過程有一個(gè)基本的了解之后,請(qǐng)?jiān)囍鴱膸讉(gè)不同的瀏覽器中訪問您的頁面。您應(yīng)該會(huì)注意到各個(gè)瀏覽器如何處理這些就緒狀態(tài)并不一致。例如,在 Firefox 1.5 中,您會(huì)看到以下就緒狀態(tài):

·1
·2
·3
·4

這并不奇怪,因?yàn)槊總(gè)請(qǐng)求狀態(tài)都在這里表示出來了。然而,如果您使用 Safari 來訪問相同的應(yīng)用程序,就應(yīng)該看到 —— 或者看不到 —— 一些有趣的事情。下面是在 Safari 2.0.1 中看到的狀態(tài):

·2
·3
·4

Safari 實(shí)際上把第一個(gè)就緒狀態(tài)給丟棄了,也并沒有什么明顯的原因說明為什么要這樣做;不過這就是 Safari 的工作方式。這還說明了一個(gè)重要的問題:盡管在使用服務(wù)器上的數(shù)據(jù)之前確保請(qǐng)求的狀態(tài)為 4 是一個(gè)好主意,但是依賴于每個(gè)過渡期就緒狀態(tài)編寫的代碼的確會(huì)在不同的瀏覽器上得到不同的結(jié)果。

例如,在使用 Opera 8.5 時(shí),所顯示的就緒狀態(tài)情況就更加糟糕了:

·3
·4

最后,Internet Explorer 會(huì)顯示如下狀態(tài):

·1
·2
·3
·4

如果您碰到請(qǐng)求方面的問題,這就是用來發(fā)現(xiàn)問題的 首要之處。最好的方式是在 Internet Explorer 和 Firefox 都進(jìn)行一下測(cè)試 —— 您會(huì)看到所有這 4 種狀態(tài),并可以檢查請(qǐng)求的每個(gè)狀態(tài)所處的情況。

接下來我們?cè)賮砜匆幌马憫?yīng)端的情況。

顯微鏡下的響應(yīng)數(shù)據(jù)

一旦我們理解在請(qǐng)求過程中發(fā)生的各個(gè)就緒狀態(tài)之后,接下來就可以來看一下 XMLHttpRequest 對(duì)象的另外一個(gè)方面了 —— responseText 屬性。回想一下在上一篇文章中我們介紹過的內(nèi)容,就可以知道這個(gè)屬性用來從服務(wù)器上獲取數(shù)據(jù)。一旦服務(wù)器完成對(duì)請(qǐng)求的處理之后,就可以將響應(yīng)請(qǐng)求數(shù)據(jù)所需要的任何數(shù)據(jù)放到請(qǐng)求的 responseText 中了。然后回調(diào)函數(shù)就可以使用這些數(shù)據(jù),如 清單 1 和 清單 4 所示。

清單 4. 使用服務(wù)器上返回的響應(yīng)

 

function updatePage() {
if (request.readyState == 4) {
var newTotal = request.responseText;
var totalSoldEl = document.getElementById("total-sold");
var netProfitEl = document.getElementById("net-profit");
replaceText(totalSoldEl, newTotal);

/* 圖 out the new net profit */
var boardCostEl = document.getElementById("board-cost");
var boardCost = getText(boardCostEl);
var manCostEl = document.getElementById("man-cost");
var manCost = getText(manCostEl);
var profitPerBoard = boardCost - manCost;
var netProfit = profitPerBoard * newTotal;

/* Update the net profit on the sales form */
netProfit = Math.round(netProfit * 100) / 100;
replaceText(netProfitEl, netProfit);
}

清單 1 相當(dāng)簡單;清單 4 稍微有點(diǎn)復(fù)雜,但是它們?cè)陂_始時(shí)都要檢查就緒狀態(tài),并獲取 responseText 屬性的值。

查看請(qǐng)求的響應(yīng)文本

與就緒狀態(tài)類似,responseText 屬性的值在整個(gè)請(qǐng)求的生命周期中也會(huì)發(fā)生變化。要查看這種變化,請(qǐng)使用如 清單 5 所示的代碼來測(cè)試請(qǐng)求的響應(yīng)文本,以及它們的就緒狀態(tài)。

清單 5. 測(cè)試 responseText 屬性

function updatePage() {
// Output the current ready state
alert("updatePage() called with ready state of " + request.readyState +
" and a response text of '" + request.responseText + "'");
}

現(xiàn)在在瀏覽器中打開 Web 應(yīng)用程序,并激活您的請(qǐng)求。要更好地看到這段代碼的效果,請(qǐng)使用 Firefox 或 Internet Explorer,因?yàn)檫@兩個(gè)瀏覽器都可以報(bào)告出請(qǐng)求過程中所有可能的就緒狀態(tài)。例如在就緒狀態(tài) 2 中,就沒有定義 responseText (請(qǐng)參見 圖 3);如果 JavaScript 控制臺(tái)也已經(jīng)打開了,您就會(huì)看到一個(gè)錯(cuò)誤。

圖 3. 就緒狀態(tài)為 2 的響應(yīng)文本

不過在就緒狀態(tài) 3 中,服務(wù)器已經(jīng)在 responseText 屬性中放上了一個(gè)值,至少在這個(gè)例子中是這樣(請(qǐng)參見 圖 4)。

圖 4. 就緒狀態(tài)為 3 的響應(yīng)文本

您會(huì)看到就緒狀態(tài)為 3 的響應(yīng)在每個(gè)腳本、每個(gè)服務(wù)器甚至每個(gè)瀏覽器上都是不一樣的。不過,這在調(diào)試應(yīng)用程序中依然是非常有用的。

獲取安全數(shù)據(jù)

所有的文檔和規(guī)范都強(qiáng)調(diào),只有在就緒狀態(tài)為 4 時(shí)數(shù)據(jù)才可以安全使用。相信我,當(dāng)就緒狀態(tài)為 3 時(shí),您很少能找到無法從 responseText 屬性獲取數(shù)據(jù)的情況。然而,在應(yīng)用程序中將自己的邏輯依賴于就緒狀態(tài) 3 可不是什么好主意 —— 一旦您編寫了依賴于就緒狀態(tài) 3 的完整數(shù)據(jù)的的代碼,幾乎就要自己來負(fù)責(zé)當(dāng)時(shí)的數(shù)據(jù)不完整問題了。

比較好的做法是向用戶提供一些反饋,說明在處于就緒狀態(tài) 3 時(shí),很快就會(huì)有響應(yīng)了。盡管使用 alert() 之類的函數(shù)顯然不是什么好主意 —— 使用 Ajax 然后使用一個(gè)警告對(duì)話框來阻塞用戶顯然是錯(cuò)誤的 —— 不過您可以在就緒狀態(tài)發(fā)生變化時(shí)更新表單或頁面中的域。例如,對(duì)于就緒狀態(tài) 1 來說要將進(jìn)度指示器的寬度設(shè)置為 25%,對(duì)于就緒狀態(tài) 2 來說要將進(jìn)度指示器的寬度設(shè)置為 50%,對(duì)于就緒狀態(tài) 3 來說要將進(jìn)度指示器的寬度設(shè)置為 75%,當(dāng)就緒狀態(tài)為 4 時(shí)將進(jìn)度指示器的寬度設(shè)置為 100%(完成)。

當(dāng)然,正如您已經(jīng)看到的一樣,這種方法非常聰明,但它是依賴于瀏覽器的。在 Opera 上,您永遠(yuǎn)都不會(huì)看到前兩個(gè)就緒狀態(tài),而在 Safari 上則沒有第一個(gè)(1)。由于這個(gè)原因,我將這段代碼留作練習(xí),而沒有在本文中包括進(jìn)來。

現(xiàn)在應(yīng)該來看一下狀態(tài)代碼了。

深入了解 HTTP 狀態(tài)代碼

有了就緒狀態(tài)和您在 Ajax 編程技術(shù)中學(xué)習(xí)到的服務(wù)器的響應(yīng),您就可以為 Ajax 應(yīng)用程序添加另外一級(jí)復(fù)雜性了 —— 這要使用 HTTP 狀態(tài)代碼。這些代碼對(duì)于 Ajax 來說并沒有什么新鮮。從 Web 出現(xiàn)以來,它們就已經(jīng)存在了。在 Web 瀏覽器中您可能已經(jīng)看到過幾個(gè)狀態(tài)代碼:

·401:未經(jīng)授權(quán)
·403:禁止
·404:沒找到

您可以找到更多的狀態(tài)代碼(完整清單請(qǐng)參見 參考資料)。要為 Ajax 應(yīng)用程序另外添加一層控制和響應(yīng)(以及更為健壯的錯(cuò)誤處理)機(jī)制,您需要適當(dāng)?shù)夭榭凑?qǐng)求和響應(yīng)中的狀態(tài)代碼。

200:一切正常

在很多 Ajax 應(yīng)用程序中,您將看到一個(gè)回調(diào)函數(shù),它負(fù)責(zé)檢查就緒狀態(tài),然后繼續(xù)利用從服務(wù)器響應(yīng)中返回的數(shù)據(jù),如 清單 6 所示。

清單 6. 忽略狀態(tài)代碼的回調(diào)函數(shù)

function updatePage() {
if (request.readyState == 4) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
}
}

這對(duì)于 Ajax 編程來說證明是一種短視而錯(cuò)誤的方法。如果腳本需要認(rèn)證,而請(qǐng)求卻沒有提供有效的證書,那么服務(wù)器就會(huì)返回諸如 403 或 401 之類的錯(cuò)誤代碼。然而,由于服務(wù)器對(duì)請(qǐng)求進(jìn)行了應(yīng)答,因此就緒狀態(tài)就被設(shè)置為 4(即使應(yīng)答并不是請(qǐng)求所期望的也是如此)。最終,用戶沒有獲得有效數(shù)據(jù),當(dāng) JavaScript 試圖使用不存在的服務(wù)器數(shù)據(jù)時(shí)就可能會(huì)出現(xiàn)嚴(yán)重的錯(cuò)誤。

它花費(fèi)了最小的努力來確保服務(wù)器不但完成了一個(gè)請(qǐng)求,而且還返回了一個(gè) “一切良好” 的狀態(tài)代碼。這個(gè)代碼是 "200",它是通過 XMLHttpRequest 對(duì)象的 status 屬性來報(bào)告的。為了確保服務(wù)器不但完成了一個(gè)請(qǐng)求,而且還報(bào)告了一個(gè) OK 狀態(tài),請(qǐng)?jiān)谀幕卣{(diào)函數(shù)中添加另外一個(gè)檢查功能,如 清單 7 所示。

清單 7. 檢查有效狀態(tài)代碼

function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
} else
alert("status is " + request.status);
}
}

通過添加這幾行代碼,您就可以確認(rèn)是否存在問題,用戶會(huì)看到一個(gè)有用的錯(cuò)誤消息,而不僅僅是看到一個(gè)由斷章取義的數(shù)據(jù)所構(gòu)成的頁面,而沒有任何解釋。

重定向和重新路由

在深入介紹有關(guān)錯(cuò)誤的內(nèi)容之前,我們有必要來討論一下有關(guān)一個(gè)在使用 Ajax 時(shí) 并不需要 關(guān)心的問題 —— 重定向。在 HTTP 狀態(tài)代碼中,這是 300 系列的狀態(tài)代碼,包括:

·301:永久移動(dòng)
·302:找到(請(qǐng)求被重新定向到另外一個(gè) URL/URI 上)
·305:使用代理(請(qǐng)求必須使用一個(gè)代理來訪問所請(qǐng)求的資源)

Ajax 程序員可能并不太關(guān)心有關(guān)重定向的問題,這是由于兩方面的原因:

·首先,Ajax 應(yīng)用程序通常都是為一個(gè)特定的服務(wù)器端腳本、servlet 或應(yīng)用程序而編寫的。對(duì)于那些您看不到就消失了的組件來說,Ajax 程序員就不太清楚了。因此有時(shí)您會(huì)知道資源已經(jīng)移動(dòng)了(因?yàn)槟苿?dòng)了它,或者通過某種手段移動(dòng)了它),接下來要修改請(qǐng)求中的 URL,并且不會(huì)再碰到這種結(jié)果了。
更為重要的一個(gè)原因是:Ajax 應(yīng)用程序和請(qǐng)求都是封裝在沙盒中的。這就意味著提供生成 Ajax 請(qǐng)求的 Web 頁面的域必須是對(duì)這些請(qǐng)求進(jìn)行響應(yīng)的域。因此 ebay.com 所提供的 Web 頁面就不能對(duì)一個(gè)在 amazon.com 上運(yùn)行的腳本生成一個(gè) Ajax 風(fēng)格的請(qǐng)求;在 ibm.com 上的 Ajax 應(yīng)用程序也無法對(duì)在 netbeans.org 上運(yùn)行的 servlets 發(fā)出請(qǐng)求。
·結(jié)果是您的請(qǐng)求無法重定向到其他服務(wù)器上,而不會(huì)產(chǎn)生安全性錯(cuò)誤。在這些情況中,您根本就不會(huì)得到狀態(tài)代碼。通常在調(diào)試控制臺(tái)中都會(huì)產(chǎn)生一個(gè) JavaScript 錯(cuò)誤。因此,在對(duì)狀態(tài)代碼進(jìn)行充分的考慮之后,您就可以完全忽略重定向代碼的問題了。

結(jié)果是您的請(qǐng)求無法重定向到其他服務(wù)器上,而不會(huì)產(chǎn)生安全性錯(cuò)誤。在這些情況中,您根本就不會(huì)得到狀態(tài)代碼。通常在調(diào)試控制臺(tái)中都會(huì)產(chǎn)生一個(gè) JavaScript 錯(cuò)誤。因此,在對(duì)狀態(tài)代碼進(jìn)行充分的考慮之后,您就可以完全忽略重定向代碼的問題了。

錯(cuò)誤

一旦接收到狀態(tài)代碼 200 并且意識(shí)到可以很大程度上忽略 300 系列的狀態(tài)代碼之后,所需要擔(dān)心的唯一一組代碼就是 400 系列的代碼了,這說明了不同類型的錯(cuò)誤。回頭再來看一下 清單 7,并注意在對(duì)錯(cuò)誤進(jìn)行處理時(shí),只將少數(shù)常見的錯(cuò)誤消息輸出給用戶了。盡管這是朝正確方向前進(jìn)的一步,但是要告訴從事應(yīng)用程序開發(fā)的用戶和程序員究竟發(fā)生了什么問題,這些消息仍然是沒有太大用處的。

首先,我們要添加對(duì)找不到的頁的支持。實(shí)際上這在大部分產(chǎn)品系統(tǒng)中都不應(yīng)該出現(xiàn),但是在測(cè)試腳本位置發(fā)生變化或程序員輸入了錯(cuò)誤的 URL 時(shí),這種情況并不罕見。如果您可以自然地報(bào)告 404 錯(cuò)誤,就可以為那些困擾不堪的用戶和程序員提供更多幫助。例如,如果服務(wù)器上的一個(gè)腳本被刪除了,我們就可以使用 清單 7 中的代碼,這樣用戶就會(huì)看到一個(gè)如 圖 5 所示的非描述性錯(cuò)誤。

邊界情況和困難情況

看到現(xiàn)在,一些新手程序員就可能會(huì)這究竟是要討論什么內(nèi)容。有一點(diǎn)事實(shí)大家需要知道:只有不到 5% 的 Ajax 請(qǐng)求需要使用諸如 2、3 之類的就緒狀態(tài)和諸如 403 之類的狀態(tài)代碼(實(shí)際上,這個(gè)比率可能更接近于 1% 甚至更少)。這些情況非常重要,稱為 邊界情況(edge case) —— 它們只會(huì)在一些非常特殊的情況下發(fā)生,其中遇到的都是最奇特的問題。雖然這些情況并不普遍,但是這些邊界情況卻占據(jù)了大部分用戶所碰到的問題的 80%!

對(duì)于典型的用戶來說,應(yīng)用程序 100 次都是正常工作的這個(gè)事實(shí)通常都會(huì)被忘記,然而應(yīng)用程序只要一次出錯(cuò)就會(huì)被他們清楚地記住。如果您可以很好地處理邊界情況(或困難情況),就可以為再次訪問站點(diǎn)的用戶提供滿意的回報(bào)。

圖 5. 常見錯(cuò)誤處理

用戶無法判斷問題究竟是認(rèn)證問題、沒找到腳本(此處就是這種情況)、用戶錯(cuò)誤還是代碼中有些地方產(chǎn)生了問題。添加一些簡單的代碼可以讓這個(gè)錯(cuò)誤更加具體。請(qǐng)參照 清單 8,它負(fù)責(zé)處理沒找到的腳本或認(rèn)證發(fā)生錯(cuò)誤的情況,在出現(xiàn)這些錯(cuò)誤時(shí)都會(huì)給出具體的消息。

清單 8. 檢查有效狀態(tài)代碼

function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
} else if (request.status == 404) {
alert ("Requested URL is not found.");
} else if (request.status == 403) {
alert("Access denied.");
} else
alert("status is " + request.status);
}
}

雖然這依然相當(dāng)簡單,但是它的確多提供了一些有用的信息。圖 6 給出了與 圖 5 相同的錯(cuò)誤,但是這一次錯(cuò)誤處理代碼向用戶或程序員更好地說明了究竟發(fā)生了什么。

圖 6. 特殊錯(cuò)誤處理

在我們自己的應(yīng)用程序中,可以考慮在發(fā)生認(rèn)證失敗的情況時(shí)清除用戶名和密碼,并向屏幕上添加一條錯(cuò)誤消息。我們可以使用類似的方法來更好地處理找不到腳本或其他 400 類型的錯(cuò)誤(例如 405 表示不允許使用諸如發(fā)送 HEAD 請(qǐng)求之類不可接受的請(qǐng)求方法,而 407 則表示需要進(jìn)行代理認(rèn)證)。然而不管采用哪種選擇,都需要從對(duì)服務(wù)器上返回的狀態(tài)代碼開始入手進(jìn)行處理。

其他請(qǐng)求類型

如果您真希望控制 XMLHttpRequest 對(duì)象,可以考慮最后實(shí)現(xiàn)這種功能 —— 將 HEAD 請(qǐng)求添加到指令中。在前兩篇文章中,我們已經(jīng)介紹了如何生成 GET 請(qǐng)求;在馬上就要發(fā)表的一篇文章中,您會(huì)學(xué)習(xí)有關(guān)使用 POST 請(qǐng)求將數(shù)據(jù)發(fā)送到服務(wù)器上的知識(shí)。不過本著增強(qiáng)錯(cuò)誤處理和信息搜集的精神,您應(yīng)該學(xué)習(xí)如何生成 HEAD 請(qǐng)求。

生成請(qǐng)求

實(shí)際上生成 HEAD 請(qǐng)求非常簡單;您可以使用 "HEAD"(而不是 "GET" 或 "POST")作為第一個(gè)參數(shù)來調(diào)用 open() 方法,如 清單 9 所示。

清單 9. 使用 Ajax 生成一個(gè) HEAD 請(qǐng)求

function getSalesData() {
createRequest();
var url = "/boards/servlet/UpdateBoardSales";
request.open("HEAD", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}

當(dāng)您這樣生成一個(gè) HEAD 請(qǐng)求時(shí),服務(wù)器并不會(huì)像對(duì) GET 或 POST 請(qǐng)求一樣返回一個(gè)真正的響應(yīng)。相反,服務(wù)器只會(huì)返回資源的 頭(header),這包括響應(yīng)中內(nèi)容最后修改的時(shí)間、請(qǐng)求資源是否存在和很多其他有用信息。您可以在服務(wù)器處理并返回資源之前使用這些信息來了解有關(guān)資源的信息。

對(duì)于這種請(qǐng)求您可以做的最簡單的事情就是簡單地輸出所有的響應(yīng)頭的內(nèi)容。這可以讓您了解通過 HEAD 請(qǐng)求可以使用什么。清單 10 提供了一個(gè)簡單的回調(diào)函數(shù),用來輸出從 HEAD 請(qǐng)求中獲得的響應(yīng)頭的內(nèi)容。

清單 10. 輸出從 HEAD 請(qǐng)求中獲得的響應(yīng)頭的內(nèi)容

function updatePage() {
if (request.readyState == 4) {
alert(request.getAllResponseHeaders());
}
}

請(qǐng)參見 圖 7,其中顯示了從一個(gè)向服務(wù)器發(fā)出的 HEAD 請(qǐng)求的簡單 Ajax 應(yīng)用程序返回的響應(yīng)頭。

您可以單獨(dú)使用這些頭(從服務(wù)器類型到內(nèi)容類型)在 Ajax 應(yīng)用程序中提供其他信息或功能。

檢查 URL

您已經(jīng)看到了當(dāng) URL 不存在時(shí)應(yīng)該如何檢查 404 錯(cuò)誤。如果這變成一個(gè)常見的問題 —— 可能是缺少了一個(gè)特定的腳本或 servlet —— 那么您就可能會(huì)希望在生成完整的 GET 或 POST 請(qǐng)求之前來檢查這個(gè) URL。要實(shí)現(xiàn)這種功能,生成一個(gè) HEAD 請(qǐng)求,然后在回調(diào)函數(shù)中檢查 404 錯(cuò)誤;清單 11 給出了一個(gè)簡單的回調(diào)函數(shù)。

清單 11. 檢查某個(gè) URL 是否存在

function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
alert("URL exists");
} else if (request.status == 404) {
alert("URL does not exist.");
} else {
alert("Status is: " + request.status);
}
}
}

誠實(shí)地說,這段代碼的價(jià)值并不太大。服務(wù)器必須對(duì)請(qǐng)求進(jìn)行響應(yīng),并構(gòu)造一個(gè)響應(yīng)來填充內(nèi)容長度的響應(yīng)頭,因此并不能節(jié)省任何處理時(shí)間。另外,這花費(fèi)的時(shí)間與生成請(qǐng)求并使用 HEAD 請(qǐng)求來查看 URL 是否存在所需要的時(shí)間一樣多,因?yàn)樗墒褂?GET 或 POST 的請(qǐng)求,而不僅僅是如 清單 7 所示一樣來處理錯(cuò)誤代碼。不過,有時(shí)確切地了解目前什么可用也是非常有用的;您永遠(yuǎn)不會(huì)知道何時(shí)創(chuàng)造力就會(huì)迸發(fā)或者何時(shí)需要 HEAD 請(qǐng)求!

有用的 HEAD 請(qǐng)求

您會(huì)發(fā)現(xiàn) HEAD 請(qǐng)求非常有用的一個(gè)領(lǐng)域是用來查看內(nèi)容的長度或內(nèi)容的類型。這樣可以確定是否需要發(fā)回大量數(shù)據(jù)來處理請(qǐng)求,和服務(wù)器是否試圖返回二進(jìn)制數(shù)據(jù),而不是 HTML、文本或 XML(在 JavaScript 中,這 3 種類型的數(shù)據(jù)都比二進(jìn)制數(shù)據(jù)更容易處理)。

在這些情況中,您只使用了適當(dāng)?shù)念^名,并將其傳遞給 XMLHttpRequest 對(duì)象的 getResponseHeader() 方法。因此要獲取響應(yīng)的長度,只需要調(diào)用 request.getResponseHeader("Content-Length");。要獲取內(nèi)容類型,請(qǐng)使用 request.getResponseHeader("Content-Type");。在很多應(yīng)用程序中,生成 HEAD 請(qǐng)求并沒有增加任何功能,甚至可能會(huì)導(dǎo)致請(qǐng)求速度變慢(通過強(qiáng)制生成一個(gè) HEAD 請(qǐng)求來獲取有關(guān)響應(yīng)的數(shù)據(jù),然后在使用一個(gè) GET 或 POST 請(qǐng)求來真正獲取響應(yīng))。然而,在出現(xiàn)您不確定有關(guān)腳本或服務(wù)器端組件的情況時(shí),使用 HEAD 請(qǐng)求可以獲取一些基本的數(shù)據(jù),而不需要對(duì)響應(yīng)數(shù)據(jù)真正進(jìn)行處理,也不需要大量的帶寬來發(fā)送響應(yīng)。

結(jié)束語

對(duì)于很多 Ajax 和 Web 程序員來說,本文中介紹的內(nèi)容似乎是太高級(jí)了。生成 HEAD 請(qǐng)求的價(jià)值是什么呢?到底在什么情況下需要在 JavaScript 中顯式地處理重定向狀態(tài)代碼呢?這些都是很好的問題;對(duì)于簡單的應(yīng)用程序來說,答案是這些高級(jí)技術(shù)的價(jià)值并不是非常大。然而,Web 已經(jīng)不再是只需實(shí)現(xiàn)簡單應(yīng)用程序的地方了;用戶已經(jīng)變得更加高級(jí),客戶期望能夠獲得更好的穩(wěn)定性、更高級(jí)的錯(cuò)誤報(bào)告,如果應(yīng)用程序有 1% 的時(shí)間停機(jī),那么經(jīng)理就可能會(huì)因此而被解雇。因此您的工作就不能僅僅局限于簡單的應(yīng)用程序了,而是需要更深入理解 XMLHttpRequest。

·如果您可以考慮各種就緒狀態(tài) —— 并且理解了這些就緒狀態(tài)在不同瀏覽器之間的區(qū)別 —— 就可以快速調(diào)試應(yīng)用程序了。您甚至可以基于就緒狀態(tài)而開發(fā)一些創(chuàng)造性的功能,并向用戶和客戶回報(bào)請(qǐng)求的狀態(tài)。
·如果您要對(duì)狀態(tài)代碼進(jìn)行控制,就可以設(shè)置應(yīng)用程序來處理腳本錯(cuò)誤、非預(yù)期的響應(yīng)以及邊緣情況。結(jié)果是應(yīng)用程序在所有的時(shí)間都可以正常工作,而不僅僅是只能一切都正常的情況下才能運(yùn)行。
·增加這種生成 HEAD 請(qǐng)求的能力,檢查某個(gè) URL 是否存在,以及確認(rèn)某個(gè)文件是否被修改過,這樣就可以確保用戶可以獲得有效的頁面,用戶所看到的信息都是最新的,(最重要的是)讓他們驚訝這個(gè)應(yīng)用程序是如何健壯和通用。

 

分享:怎樣用DHTML與XML制作Ajax幻燈片
Ajax 幻燈片放映 個(gè)人圖像管理應(yīng)用程序(如 Macintosh 上的 Apple iPhoto)使得幻燈片瀏覽廣為人知。在幻燈片瀏覽中,圖像按照時(shí)間順序先后淡入淡出。此外,圖片還通過所謂的 “Ken Burns Effect” 進(jìn)行移動(dòng)和縮放。 在該例中,我讓瀏覽器從服務(wù)器上下載一個(gè)

來源:模板無憂//所屬分類:AJAX教程/更新時(shí)間:2010-04-25
相關(guān)AJAX教程
亚洲免费成人av在线| 久久久久久成人网| av一级黄色片| 亚洲美女啪啪| 欧美亚洲一区二区在线| 91精品久久久久久久久青青 | 国产又黄又猛又粗| 国产片在线播放| aⅴ色国产欧美| 欧美日韩aaaaaa| 国产精品区一区二区三在线播放| 青青草福利视频| 亚洲日韩中文字幕一区| 成人免费不卡视频| 最近2019中文字幕第三页视频| 成人国产一区二区三区| 日韩精品成人免费观看视频| 91精品国产自产在线观看永久∴| 亚洲国产成人tv| 国产精品久久久久免费a∨| 男男受被啪到高潮自述| 亚洲成人人体| 成人黄色一级视频| www国产精品com| 欧美 日韩 国产一区| 97在线视频人妻无码| 久久九九免费| 亚洲国产又黄又爽女人高潮的| 日韩精品资源| 国产69精品久久久久久久久久| 亚洲欧洲日韩| 日本韩国精品在线| 国产精品日韩欧美一区二区三区 | 亚洲精品永久免费视频| 国产一区二区三区黄视频| 日韩第一页在线| 水蜜桃一区二区| www.天天色| 中文字幕一区二区三区欧美日韩| 91官网在线免费观看| 激情视频在线观看一区二区三区| 男人在线观看视频| 日韩中文字幕高清在线观看| 欧美日韩一区二区精品| 国产精品久久国产精品| 国产精品视频看看| 日本久久综合| 欧美日韩中字一区| 欧美18视频| 久久一区二区三区视频| 国产一区久久| 日韩三级免费观看| 成年人黄色在线观看| 精品国产www| 国产精品亚洲欧美| 精品亚洲国产成av人片传媒| 免费观看美女裸体网站 | 精品亚洲aⅴ在线观看| 欧美激情视频免费看| 国精品人妻无码一区二区三区喝尿 | 欧美一级淫片videoshd| bl动漫在线观看| 欧美顶级毛片在线播放| 午夜久久福利影院| 精品欧美一区二区三区久久久| 国产亚洲精品成人| 亚洲精品1234| 亚洲精品丝袜日韩| 欧美视频第三页| se69色成人网wwwsex| 国产欧美一区二区精品久导航 | 欧美这里有精品| 视频在线99re| 97国产成人无码精品久久久| 国产精品亚洲一区二区三区在线| 欧美激情精品久久久| 国产精品熟妇一区二区三区四区| 国产成人澳门| 色综合色综合色综合色综合色综合 | 欧美三级网色| 一本色道久久综合亚洲| 国产麻豆日韩欧美久久| 久久久亚洲国产| 欧美图片一区二区| 欧美r级电影| 欧美成人r级一区二区三区| 国产在线播放观看| 成人开心激情| 亚洲欧美乱综合| 精品视频高清无人区区二区三区| 91精品国产综合久久久蜜臀九色| 日韩av一区二区在线影视| 色综久久综合桃花网| 亚洲成人av免费观看| 欧美黄色网视频| 在线视频国内一区二区| 喜爱夜蒲2在线| 毛片免费看不卡网站| 国产精品你懂的在线欣赏| 3d精品h动漫啪啪一区二区| 91香蕉在线视频| 男女男精品视频| 久久久久久91香蕉国产| 亚洲精品成人无码熟妇在线| 五月精品视频| 日韩精品在线观看网站| 久久出品必属精品| 精品一区毛片| 日韩亚洲欧美一区二区三区| 日韩中文字幕二区| 亚洲视频国产精品| 欧美亚洲动漫精品| 奇米影视亚洲色图| 亚洲伦理一区二区| 色婷婷av一区二区| 欧美交换配乱吟粗大25p| 第四色男人最爱上成人网| 亚洲一区二区在线视频| 亚洲国产激情一区二区三区| 蜜臀久久99精品久久久| 久久久精品免费免费| 9国产精品视频| 亚洲精品视频一区二区| 蜜桃精品久久久久久久免费影院| 国产精品老熟女视频一区二区| 91一区一区三区| 成人9ⅰ免费影视网站| 久久国产香蕉视频| 91免费国产在线观看| 99国产超薄丝袜足j在线观看| 天堂av免费在线观看| 菠萝蜜视频在线观看一区| 成人午夜两性视频| 中文字幕在线观看国产| 久久久久久97三级| 精品久久久久久乱码天堂| 国产片在线播放| 亚洲欧洲一区二区三区| 视频一区不卡| 中文字幕日本一区二区| 欧美日韩中文字幕综合视频| 九九精品在线视频| 18成人在线| 日本少妇久久久| 国产成人久久精品77777最新版本| 国产精品99久久久久久人| 看片网址国产福利av中文字幕| 国产91丝袜在线18| 亚洲综合在线播放| 精品区在线观看| 一区二区三区在线视频免费| av电影一区二区三区| 亚洲一区有码| 51精品秘密在线观看| 中文字幕一区久久| 亚洲成人av| 久久国产加勒比精品无码| 成人黄色短视频| 极品尤物av久久免费看| 成人激情视频在线观看| 中文字幕在线网址| 一区精品在线播放| 天天想你在线观看完整版电影免费| 9.1麻豆精品| 欧美一级黄色片| 免费观看一区二区三区| 影音先锋在线一区| 国模精品系列视频| 亚洲日本视频在线观看| 亚洲国产精品二十页| 亚洲午夜在线观看| 欧美日韩中出| 日韩精品资源二区在线| 娇妻高潮浓精白浆xxⅹ| 亚洲在线国产日韩欧美| 日本欧美精品在线| 亚洲一二区视频| 亚洲天堂av一区| 欧美成人精品免费| 欧美五码在线| 中文字幕欧美视频在线| 天海翼在线视频| 成人av网站免费观看| 欧美极品视频一区二区三区| 激情欧美一区二区三区黑长吊| 欧美老年两性高潮| 成人做爰www看视频软件| 亚洲经典三级| 国产精品天天狠天天看| www.超碰在线.com| 日韩欧美亚洲一二三区| 青青草原国产在线视频| 亚洲国产精品一区| 国产精品欧美亚洲777777| 99视频国产精品免费观看a| 婷婷国产v国产偷v亚洲高清| 久久精品一区二区三区四区| 亚洲一区二区在线| 五月婷婷丁香六月| 欧美日韩高清在线| 黄色av网址在线观看| 卡一卡二国产精品| 久久国产精品一区二区三区| 2020国产精品小视频| 日韩电影中文字幕在线观看| 日韩精品123区| 久久综合九色综合欧美就去吻 | 久久综合色8888| 亚洲在线色站| 欧美一级全黄| 久久国产精彩视频| 免费看一级视频| 亚洲国产aⅴ成人精品无吗| 国产精品拍拍拍| 久久动漫亚洲| 成人免费在线一区二区三区| 精品美女一区| 亚洲精品视频在线观看视频| 欧美成人精品欧美一级| 国产精品拍天天在线| 国产免费黄色av| 欧美午夜国产| 亚洲aⅴ日韩av电影在线观看| 台湾成人免费视频| 日韩电影免费观看在线观看| 免费在线一区二区三区| 国产精品短视频| 成人一区二区三| 亚洲欧美视频| 国产欧美日韩亚洲| 一级毛片精品毛片| 精品国产欧美一区二区五十路| 亚洲天堂男人av| 欧美性精品220| 国产精品嫩草av| 99久久国产综合色|国产精品| 午夜成人在线视频| 成人在线视频网| 日韩经典一区| 亚洲天堂一区二区三区| 影音先锋亚洲天堂| 婷婷六月综合亚洲| 稀缺小u女呦精品呦| 国产成人自拍网| 亚洲小视频在线播放| 综合激情一区| 亚洲综合小说区| 白嫩白嫩国产精品| 欧美精品久久久久久久免费观看 | 欧美xxx网站| 日韩精品免费视频| 依依成人综合网| 欧美亚洲国产一区在线观看网站| 欧美另类z0zx974| 国产精品污网站| www.激情小说.com| 美女尤物国产一区| 亚洲一区二区在线看| 999精品色在线播放| 成人写真福利网| baoyu135国产精品免费| 国内精品久久久久久久久| 日韩一区免费视频| 亚洲精品理论电影| 久久久久久久久黄色| 欧美日韩一级视频| 黄色录像免费观看| 亚洲国产视频直播| 日本xxxx裸体xxxx| 中文字幕精品—区二区四季| 制服丝袜中文字幕第一页| 欧美综合影院| 国产精品卡一卡二| 中文字幕12页| 成人一级黄色片| 国产l精品国产亚洲区久久| 香蕉久久夜色精品| 亚洲精品永久www嫩草| 欧美在线网址| 国内视频一区二区| 欧美最新另类人妖| 亚洲一区二区少妇| 亚洲警察之高压线| 国产欧美日韩中文| 超碰97成人| 国产精品高潮呻吟久久av无限| 成人av在线播放| 国内精品久久久久影院优| 久久久人成影片一区二区三区在哪下载| 中文字幕亚洲综合久久筱田步美| 国产麻豆一精品一男同| 日韩精品久久久久久久玫瑰园| 中文字幕网址在线| 精品盗摄一区二区三区| 亚洲男人天堂网址| 精品国产乱码久久久久久影片| 国产午夜精品久久久久| 欧美一区二区三区色| 国产成人在线播放视频| 欧美肥胖老妇做爰| 国产专区第一页| 91精品国产高清一区二区三区 | 久久偷窥视频| 影音先锋成人在线电影| 久久五月天婷婷| 国产精品chinese| 神马影院我不卡午夜| 国产亚洲一区在线| 91xxx视频| 日韩和的一区二在线| 午夜成人免费视频| 国产黄色小视频网站| 欧美性猛交xxxx富婆弯腰| 国产十六处破外女视频| 在线观看91精品国产入口| 国产亚洲精品久久久久久打不开| 欧美色电影在线| 欧美精品二区三区| 精品久久久久一区二区国产| 国产精品毛片一区二区在线看舒淇 | 精品露脸国产偷人在视频| 成人涩涩小片视频日本| 欧美视频中文一区二区三区在线观看| 日韩精品一区二区三区国语自制| 7777精品伊人久久久大香线蕉最新版| 黄色av网站免费观看| 日韩av一区二区在线| 韩国av永久免费| 欧美日韩第一视频| 96视频在线观看欧美| 国产精品电影网| 一区二区三区视频免费观看| 国产精品久久亚洲7777| 国内精品久久久久久久97牛牛| 亚洲一区二区三区涩| 免费欧美在线视频| 国产精品99久久免费黑人人妻| 99久久99久久精品免费观看| 国产chinese中国hdxxxx| 亚洲精品乱码久久久久久黑人 | 自拍偷拍18p| 亚洲欧美一区二区三区久久| 三级网站在线看| 97色在线观看| 日韩激情网站| 久久久www免费人成黑人精品| 国产人妖在线观看| 亚洲欧美影音先锋| 99久久久无码国产精品不卡| 精品视频一区二区三区免费| 国产女主播喷水视频在线观看| 亚洲色图日韩av| 精品176极品一区| 91久久国产精品91久久性色| 亚洲大全视频| 日韩一级特黄毛片| 成人av电影在线网| 老熟妇精品一区二区三区| 精品久久久久久中文字幕大豆网| 在线观看 中文字幕| 亚洲欧洲激情在线| 成人福利一区二区| 91久久夜色精品国产网站| 欧美特黄a级高清免费大片a级| 国产真人做爰毛片视频直播| 91久色porny| 亚洲天堂岛国片| 91精品国产91久久综合桃花| 99久久精品国产色欲| 国内外成人免费激情在线视频网站| 久久av国产紧身裤| 欧美日韩精品中文字幕一区二区| 欧美aaa在线| 欧洲美女亚洲激情| 亚洲成人午夜影院| 无码视频一区二区三区| 久久天天躁夜夜躁狠狠躁2022| 国产 日韩 欧美 综合 一区| 久久香蕉综合色| 狠狠色狠狠色合久久伊人| 毛茸茸free性熟hd| 在线观看亚洲a| 国产av无码专区亚洲a∨毛片| 性视频1819p久久| 青青草综合网| 精品人妻人人做人人爽| 久久久久国产精品免费免费搜索| 国产美女高潮视频| 亚洲第一区第二区| 久久av影院| 国产亚洲欧美一区二区| 免费在线观看一区二区三区| 日本成人在线免费| 在线区一区二视频| 精品黑人一区二区三区国语馆| 4hu四虎永久在线影院成人| 香蕉视频网站入口| 亚洲美女淫视频| 男人日女人网站| 欧美第一黄色网|