閱讀475 返回首頁    go 阿裏雲 go 技術社區[雲棲]


ajax中的高級請求和響應

對於很多 Web 開發人員來說,隻需要生成簡單的請求並接收簡單的響應即可;但是對於希望掌握 Ajax 的開發人員來說,必須要全麵理解 HTTP 狀態代碼、就緒狀態和 XMLHttpRequest 對象。在本文中,Brett McLaughlin 將向您介紹各種狀態代碼,並展示瀏覽器如何對其進行處理,本文還給出了在 Ajax 中使用的比較少見的 HTTP 請求;

  • HTTP 就緒狀態
  • HTTP 狀態代碼
  • 可以生成的請求類型



深入了解 HTTP 就緒狀態

  • 0:請求未初始化(還沒有調用 open())。
  • 1:請求已經建立,但是還沒有發送(還沒有調用 send())。
  • 2:請求已發送,正在處理中(通常現在可以從響應中獲取內容頭)。
  • 3:請求在處理中;通常響應中已有部分數據可用了,但是服務器還沒有完成響應的生成。
  • 4:響應已完成;您可以獲取並使用服務器的響應了。
如果您希望不僅僅是了解 Ajax 編程的基本知識,那麼就不但需要知道這些狀態,了解這些狀態是何時出現的,以及如何來使用這些狀態。首先,您需要學習在每種就緒狀態下可能碰到的是哪種請求狀態。不幸的是,這一點並不直觀,而且會涉及幾種特殊的情況。


深入了解 HTTP 狀態代碼


401
:未經授權 403:禁止 404:沒找到


200:一切正常
  1.    function updatePage() {
  2.      if (request.readyState == 4) {
  3.        if (request.status == 200) {
  4.          var response = request.responseText.split("|");
  5.          document.getElementById("order").value = response[0];
  6.          document.getElementById("address").innerHTML =
  7.            response[1].replace(//n/g, "<br />");
  8.        } else
  9.          alert("status is " + request.status);
  10.      }
  11.    }
通過添加這幾行代碼,您就可以確認是否存在問題,用戶會看到一個有用的錯誤消息,而不僅僅是看到一個由斷章取義的數據所構成的頁麵,而沒有任何解釋。

重定向和重新路由

在深入介紹有關錯誤的內容之前,我們有必要來討論一下有關一個在使用 Ajax 時 並不需要 關心的問題 —— 重定向。在 HTTP 狀態代碼中,這是 300 係列的狀態代碼,包括:

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

Ajax 程序員可能並不太關心有關重定向的問題,這是由於兩方麵的原因:

首先,Ajax 應用程序通常都是為一個特定的服務器端腳本、servlet 或應用程序而編寫的。對於那些您看不到就消失了的組件來說,Ajax 程序員就不太清楚了。因此有時您會知道資源已經移動了(因為您移動了它,或者通過某種手段移動了它),接下來要修改請求中的 URL,並且不會再碰到這種結果了。 更為重要的一個原因是:Ajax 應用程序和請求都是封裝在沙盒中的。這就意味著提供生成 Ajax 請求的 Web 頁麵的域必須是對這些請求進行響應的域。因此 ebay.com 所提供的 Web 頁麵就不能對一個在 amazon.com 上運行的腳本生成一個 Ajax 風格的請求;在 ibm.com 上的 Ajax 應用程序也無法對在 netbeans.org 上運行的 servlets 發出請求。

結果是您的請求無法重定向到其他服務器上,而不會產生安全性錯誤。在這些情況中,您根本就不會得到狀態代碼。通常在調試控製台中都會產生一個 JavaScript 錯誤。因此,在對狀態代碼進行充分的考慮之後,您就可以完全忽略重定向代碼的問題了。


  1. 實際上生成 HEAD 請求非常簡單;您可以使用 "HEAD"(而不是 "GET" 或 "POST")作為第一個參數來調用 open() 方法,如 清單 9 所示
  1.   function getSalesData() {
  2.      createRequest();
  3.      var url = "/boards/servlet/UpdateBoardSales";
  4.      request.open("HEAD", url, true);
  5.      request.onreadystatechange = updatePage;
  6.      request.send(null);
  7.    }

當您這樣生成一個 HEAD 請求時,服務器並不會像對 GET 或 POST 請求一樣返回一個真正的響應。相反,服務器隻會返回資源的 頭(header),這包括響應中內容最後修改的時間、請求資源是否存在和很多其他有用信息。您可以在服務器處理並返回資源之前使用這些信息來了解有關資源的信息。

對於這種請求您可以做的最簡單的事情就是簡單地輸出所有的響應頭的內容。這可以讓您了解通過 HEAD 請求可以使用什麼。清單 10 提供了一個簡單的回調函數,用來輸出從 HEAD 請求中獲得的響應頭的內容。



  1.    function updatePage() {
  2.      if (request.readyState == 4) {
  3.        alert(request.getAllResponseHeaders());
  4.      }
  5.    }

檢查 URL

您已經看到了當 URL 不存在時應該如何檢查 404 錯誤。如果這變成一個常見的問題 —— 可能是缺少了一個特定的腳本或 servlet —— 那麼您就可能會希望在生成完整的 GET 或 POST 請求之前來檢查這個 URL。要實現這種功能,生成一個 HEAD 請求,然後在回調函數中檢查 404 錯誤;清單 11 給出了一個簡單的回調函數


有用的 HEAD 請求

您會發現 HEAD 請求非常有用的一個領域是用來查看內容的長度或內容的類型。這樣可以確定是否需要發回大量數據來處理請求,和服務器是否試圖返回二進製數據,而不是 HTML、文本或 XML(在 JavaScript 中,這 3 種類型的數據都比二進製數據更容易處理)。

在這些情況中,您隻使用了適當的頭名,並將其傳遞給 XMLHttpRequest 對象的 getResponseHeader() 方法。因此要獲取響應的長度,隻需要調用request.getResponseHeader("Content-Length");。要獲取內容類型,請使用 request.getResponseHeader("Content-Type");

在很多應用程序中,生成 HEAD 請求並沒有增加任何功能,甚至可能會導致請求速度變慢(通過強製生成一個 HEAD 請求來獲取有關響應的數據,然後在使用一個 GET 或 POST 請求來真正獲取響應)。然而,在出現您不確定有關腳本或服務器端組件的情況時,使用 HEAD 請求可以獲取一些基本的數據,而不需要對響應數據真正進行處理,也不需要大量的帶寬來發送響應。

  • 如果您可以考慮各種就緒狀態 —— 並且理解了這些就緒狀態在不同瀏覽器之間的區別 —— 就可以快速調試應用程序了。您甚至可以基於就緒狀態而開發一些創造性的功能,並向用戶和客戶回報請求的狀態。
  • 如果您要對狀態代碼進行控製,就可以設置應用程序來處理腳本錯誤、非預期的響應以及邊緣情況。結果是應用程序在所有的時間都可以正常工作,而不僅僅是隻能一切都正常的情況下才能運行。
  • 增加這種生成 HEAD 請求的能力,檢查某個 URL 是否存在,以及確認某個文件是否被修改過,這樣就可以確保用戶可以獲得有效的頁麵,用戶所看到的信息都是最新的,(最重要的是)讓他們驚訝這個應用程序是如何健壯和通用。

最後更新:2017-04-02 00:06:38

  上一篇:go StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1) 中pack的理解
  下一篇:go SuperRuntimeLibrary.TextVoice 發布,支持文本到語音 文本到.wav