JavaScript >> Javascript 文檔 >  >> JavaScript

Firefox 3.5/Firebug XMLHttpRequest 和 readystatechange 錯誤

上週四,我正在調試工作中的一個問題,該問題由兩位同事使用 Firefox 3.5 報告。最初,他們沒有提到他們快速升級到最新的 Firefox,我花了一些時間試圖重現這個問題,但徒勞無功。抱怨是我們的頁面沒有顯示 Ajax 響應,即使 Firebug 清楚地顯示已收到響應。在檢查了我的代碼、頁面的其餘代碼並重新調試到 YUI 層後,我發現錯誤的根源根本不是 JavaScript 代碼——而是瀏覽器。我以為我在 Firefox 3.5 中發現了一個錯誤。

在調試時,我在推特上發布了幾次有關此問題的信息,然後 ping YUI Connection Manager 創建者 Thomas Sha 以查看他是否聽說過此問題。他沒有,所以我繼續挖掘並最終發現了兩個錯誤,一個在 Firefox 隊列中通過我的同事 Steve Carlson 和一個在 Firebug 隊列中通過 Christopher Blum。 Christopher 向我指出,他認為問題的原因實際上是 Firebug 而不是 Firefox 本身。現在已經一周過去了,問題還沒有解決,所以分享給大家,希望可以避免世界各地的web開發者大量調試。

症狀

將 Firefox 3.5 與 Firebug 1.4.x 或 1.5.x 一起使用時會出現此問題。主要症狀是 readystatechange XMLHttpRequest 上的事件 對像在 readyState 之後不會被觸發 1,表示任何腳本監聽readystatechange 測試 readyState 等於 4 將靜默失敗。沒有要捕獲的 JavaScript 錯誤,也沒有要查找的錯誤條件,實際上,響應是由瀏覽器接收的(可以使用 Firebug Net 面板或 Fiddler 進行測試)。

幸運的是,並非所有 XHR 通信都會發生這種情況。它似乎是隨機發生的,但隨著完全接收響應所需時間的增加,這種可能性也會增加。因此,與在 10 秒內收到響應的請求相比,在不到一秒的時間內收到響應的請求發生這種情況的可能性要小得多。響應返回的時間越長,readystatechange 的頻率越高 事件不會觸發。 Kyle Huey 創建了一個可重現的測試用例,允許您指定服務器在完成響應之前應該等待多長時間。我發現使用 10 或更高的值可以獲得最一致的結果(儘管我也遇到過同樣的問題,響應時間不到一秒)。

壞消息是沒有辦法檢測到這個問題正在發生。好消息是有一些變通方法。

解決方法

即使 readystatechange 事件未觸發,readyState 屬性實際上正在更新。因此,可以輪詢 readyState 中的更改 自行確定何時確定已收到響應。這是在 YUI 2.7 連接管理器中採用的方法,因此如果您使用此實用程序,您的代碼應該繼續正常工作(YUI 3 Beta 1 等效使用 onreadystatechange ,所以那個用戶會受到影響)。

如果這種方法對你來說太老套了,還有另一種解決方法。火狐 XMLHttpRequest 對象支持 W3C 進度事件,所有這些都繼續正常工作。進度事件是:

  • load – 當收到來自服務器的響應時觸發。
  • error – 發生網絡錯誤時觸發。
  • abort – 當請求被中止時觸發。
  • progress – 當響應中有部分數據可用時觸發。

在這四個中,一旦請求被認為已完成,前三個中的一個將始終被觸發(完成,我的意思是連接不再打開)。從 readystatechange 繼續在所有其他瀏覽器中工作,您可能需要在代碼中臨時分叉以同時使用進度事件,例如:

var xhr = new XMLHttpRequest();

if (firefox3_5){
    xhr.onload = xhr.onerror = xhr.onabort = function(){
        processResponse(xhr);
    };
} else {
    xhr.onreadystatechange = function(){
        if (xhr.readyState == 4){
            processResponse(xhr);
        }
    };
}

xhr.open("get", "/url", true);
xhr.send(null);

通常,我不會推薦特定於瀏覽器的 hack,但在這種情況下,我們不確定問題會持續多久,因此不知道我們的代碼會繼續中斷多久。至少,即使在此問題得到解決後,此解決方法仍將繼續有效。

正在進行的調查

Firebug 團隊和 Firefox 團隊對這個問題的討論一直在反复討論,因為這兩個團隊都試圖找出問題的原因。我親自與 Firebug 團隊的 Rob Campbell 保持聯繫,他非常致力於解決這個 bug。我還進行了大量調查(在我的知識範圍內),試圖幫助縮小問題的範圍。我發現的一些東西:

  • 在 Firefox 3.5 和 Firebug 1.4.x 或 1.5.x 中發生,包括 nightlies。
  • 在使用 Firebug 1.4.x 的 Firefox 3.0 中不會發生。
  • 在沒有安裝 Firebug 的 Firefox 3.5 中不會發生。
  • 隨著 Ajax 請求的響應時間增加,發生頻率更高。
  • 可能導致在 Firebug 控制台中以以下格式輸出錯誤:
    onreadystatechange FAILS Error:Permission denied for to create wrapper for class of unnamedClass 錯誤:Permission denied for to create wrapper for class of object UnnamedClass
    [xpconnect 包裝的 nsIDOMEventListener]

在不了解 Firefox 或 Firebug 內部如何工作的情況下,我自己的結論是 Firefox 3.5 處理 XHR 流量的變化可能會破壞 Firebug 與之掛鉤的方式。由於相同的 Firebug 版本 (1.4.x) 在 Firefox 3.0 上運行沒有問題,這將矛頭指向了 Firefox。當然,Firebug 完全有可能在做一些它不應該做的事情,在這種情況下,手指又回到了 Firebug。這就是為什麼這個問題如此難以追查的原因。

如果您的回复在短時間內返回,那麼您可能不會遇到此問題。這確實會影響那些使用 Comet 式通信(例如 Facebook 聊天)和通過高延遲連接(不穩定的無線網絡、海外服務器)發出的請求的應用程序。後者是我第一次注意到這個問題時正在處理的問題。

繼續討論 Firefox 錯誤和 Firebug 錯誤。這是更新問題的兩個地方。如果您有新的信息要添加,我想請您僅對任一錯誤發表評論。有很多“我也是”或“快點”的評論無濟於事。我知道這很令人沮喪,就像在說,“如果我們刪除 XMLHttpRequest 目的?”兩個團隊都在認真對待這個問題,並希望盡快找到解決方案。

更新(2009 年 7 月 14 日): 看起來這個問題與 Firebug 正在運行的 Firefox 3.5 中的安全更改有關。 Firebug 嘗試偵聽 XHR 對像以獲取響應的方式會導致安全錯誤,因此 readystatechange 事件變得無用。相信這個錯誤是問題的最終根源,可能需要通過 Firefox 補丁來解決。

更新(2009 年 7 月 18 日): Firefox 3.5.1 解決這個問題。解決方案仍在等待中。

更新(2009 年 7 月 23 日): Firebug 1.4.1 和 Firebug 1.5a18 修復了這個問題。感謝 Firebug 團隊的人們的辛勤付出。


Tutorial JavaScript 教程
  1. React 中的遞歸組件

  2. 如何使用 Lottie 動畫和 React JS? 🖌️

  3. 初學者完整的 JavaScript 課程

  4. 如何使用 React 創建 Youtube 克隆

  5. 20210503

  6. 將原型添加到 JavaScript 對象文字

  7. 如何在 JavaScript 中創建 3D 曲面圖

  1. 在 Drupal 7 中使用 JQuery

  2. 使用 jQuery 和 CSS 將數字轉換為星級顯示

  3. 了解 JavaScript 閉包

  4. FeathersJS 發射

  5. 學習編寫自己的測試用例第 1 部分 - 為什麼要關心以及從哪裡開始

  6. DO Hackathon Runner DevLog #1

  7. 簡單的 html 與 Javascript 生成的 html?

  1. MongoDB 簡介

  2. JS:🌈為此感到自豪

  3. 在 Angular 應用程序中動態加載組件

  4. 介紹 Dogidex 遊戲化的兒童寵物學習應用程序