欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
掌握 Ajax,第 3 部分: Ajax 中的高級請求和響應(1)
掌握 Ajax,第 3 部分: Ajax 中的高級請求和響應(1)

掌握 Ajax,第 3 部分: Ajax 中的高級請求和響應
全面理解 HTTP 的狀態(tài)代碼、就緒狀態(tài)和 XMLHttpRequest 對象
  

  文檔選項
   將此頁(yè)作為電子郵件發(fā)送

  討論

  樣例代碼



最新推薦
  Java 應用開(kāi)發(fā)源動(dòng)力 - 下載免費軟件,快速啟動(dòng)開(kāi)發(fā)




級別: 初級

Brett McLaughlin, 作家,編輯, O‘Reilly Media Inc.


2006 年 3 月 23 日

對于很多 Web 開(kāi)發(fā)人員來(lái)說(shuō),只需要生成簡(jiǎn)單的請求并接收簡(jiǎn)單的響應即可;但是對于希望掌握 Ajax 的開(kāi)發(fā)人員來(lái)說(shuō),必須要全面理解 HTTP 狀態(tài)代碼、就緒狀態(tài)和 XMLHttpRequest 對象。在本文中,Brett McLaughlin 將向您介紹各種狀態(tài)代碼,并展示瀏覽器如何對其進(jìn)行處理,本文還給出了在 Ajax 中使用的比較少見(jiàn)的 HTTP 請求。
在本系列的 上篇文章 中,我們將詳細介紹 XMLHttpRequest 對象,它是 Ajax 應用程序的中心,負責處理服務(wù)器端應用程序和腳本的請求,并處理從服務(wù)器端組件返回的數據。由于所有的 Ajax 應用程序都要使用 XMLHttpRequest 對象,因此您可能會(huì )希望熟悉這個(gè)對象,從而能夠讓 Ajax 執行得更好。

在本文中,我將在上一篇文章的基礎上重點(diǎn)介紹這個(gè)請求對象的 3 個(gè)關(guān)鍵部分的內容:

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

XMLHttpRequest 或 XMLHttp:換名玫瑰

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


下面讓我們首先來(lái)看一下 HTTP 就緒狀態(tài)。

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

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


清單 1. 在回調函數中處理服務(wù)器的響應

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)最常見(jiàn)(也是最簡(jiǎn)單)的用法。正如您從數字 "4" 中可以看出的一樣,還有其他幾個(gè)就緒狀態(tài)(您在上一篇文章中也看到過(guò)這個(gè)清單 —— 請參見(jiàn) 參考資料):

0:請求未初始化(還沒(méi)有調用 open())。
1:請求已經(jīng)建立,但是還沒(méi)有發(fā)送(還沒(méi)有調用 send())。
2:請求已發(fā)送,正在處理中(通?,F在可以從響應中獲取內容頭)。
3:請求在處理中;通常響應中已有部分數據可用了,但是服務(wù)器還沒(méi)有完成響應的生成。
4:響應已完成;您可以獲取并使用服務(wù)器的響應了。
如果您希望不僅僅是了解 Ajax 編程的基本知識,那么就不但需要知道這些狀態(tài),了解這些狀態(tài)是何時(shí)出現的,以及如何來(lái)使用這些狀態(tài)。首先,您需要學(xué)習在每種就緒狀態(tài)下可能碰到的是哪種請求狀態(tài)。不幸的是,這一點(diǎn)并不直觀(guān),而且會(huì )涉及幾種特殊的情況。

隱秘就緒狀態(tài)

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

不過(guò)為了滿(mǎn)足我們的興趣,請參見(jiàn) 清單 2 的內容,其中顯示了如何在 readyState 被設置為 0 時(shí)來(lái)獲取這種就緒狀態(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è)簡(jiǎn)單的例子中,getSalesData() 是 Web 頁(yè)面調用來(lái)啟動(dòng)請求(例如點(diǎn)擊一個(gè)按鈕時(shí))所使用的函數。注意您必須在調用 open()之前 來(lái)查看就緒狀態(tài)。圖 1 給出了運行這個(gè)應用程序的結果。


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

當 0 等于 4 時(shí)

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


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

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

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

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


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

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



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

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


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


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

瀏覽器的不一致性

在對這個(gè)過(guò)程有一個(gè)基本的了解之后,請試著(zhù)從幾個(gè)不同的瀏覽器中訪(fǎng)問(wèn)您的頁(yè)面。您應該會(huì )注意到各個(gè)瀏覽器如何處理這些就緒狀態(tài)并不一致。例如,在 Firefox 1.5 中,您會(huì )看到以下就緒狀態(tài):

1
2
3
4
這并不奇怪,因為每個(gè)請求狀態(tài)都在這里表示出來(lái)了。然而,如果您使用 Safari 來(lái)訪(fǎng)問(wèn)相同的應用程序,就應該看到 —— 或者看不到 —— 一些有趣的事情。下面是在 Safari 2.0.1 中看到的狀態(tài):

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

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

3
4
最后,Internet Explorer 會(huì )顯示如下?tīng)顟B(tài):

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

接下來(lái)我們再來(lái)看一下響應端的情況。

顯微鏡下的響應數據

一旦我們理解在請求過(guò)程中發(fā)生的各個(gè)就緒狀態(tài)之后,接下來(lái)就可以來(lái)看一下 XMLHttpRequest 對象的另外一個(gè)方面了 —— responseText 屬性?;叵胍幌略谏弦黄恼轮形覀兘榻B過(guò)的內容,就可以知道這個(gè)屬性用來(lái)從服務(wù)器上獲取數據。一旦服務(wù)器完成對請求的處理之后,就可以將響應請求數據所需要的任何數據放到請求的 responseText 中了。然后回調函數就可以使用這些數據,如 清單 1 和 清單 4 所示。


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

   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 相當簡(jiǎn)單;清單 4 稍微有點(diǎn)復雜,但是它們在開(kāi)始時(shí)都要檢查就緒狀態(tài),并獲取 responseText 屬性的值。

查看請求的響應文本

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


清單 5. 測試 responseText 屬性

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



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


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


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


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


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

獲取安全數據

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

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

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

現在應該來(lái)看一下?tīng)顟B(tài)代碼了。


完整版
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Ajax 中的高級請求和響應(1)
Ajax原生XHR對象
第 3 部分 Ajax 中的高級請求和響應(2)
Ajax工作原理及概述
AJAX基礎知識與簡(jiǎn)單的操作示例
WEB前端第六十課——原生Ajax與HTTP協(xié)議
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久