2010-11-15 180 views
1

失敗,我建立在谷歌瀏覽器的擴展,它發出的查詢對網站。Chrome擴展的消息傳遞,當XHR呼叫的jQuery

查詢是通過「背景頁」從「內容腳本」的請求發出的;當後臺頁面收到發出查詢的請求時,它會發送查詢,解析響應並使用sendResponse()將響應發送回內容腳本。

這一切都使用XMLHttpRequest的時候工作正常();但我的問題是,如果我要發出使用jQuery獲得()或.load(查詢),那麼當查詢失敗,他們默默地消失,響應從不發送到內容腳本。

如果我註冊.ajaxError()錯誤被逮住,但是從這個事件處理程序我顯然不能叫sendResponse()的事件處理程序,因爲我碰到下面的鍍鉻錯誤:

「試圖使用斷開連接端口對象」

搜索該錯誤只檢索出該文本被發現Chrome的源代碼,所以它不是非常有幫助。

總之,我的問題是:是否有可能在一個Chrome擴展的背景腳本使用jQuery.get(),並且仍然能夠發送請求失敗時的內容腳本的響應? (如果是,如何)

+0

你可以請張貼一些代碼嗎? – serg 2010-11-15 19:03:21

回答

1

這是很難的情況下直接一個代碼示例(如何是你傳遞sendResponse的錯誤處理程序來解決?),但我認爲有一些替代方案可以自己構建XHR。

  • 迴應異步:你可以立即發送一個空的響應內容腳本,然後再發起一個新的連接到內容腳本發送響應。內容腳本需要爲消息添加一個偵聽器。很明顯,如果你正在製作多個這樣的請求,你需要來回傳遞一些令牌,以便你可以將回復與原始請求進行匹配。
  • 使用$.ajax():這允許你指定一個成功和一個錯誤的回調內聯;如果您可以成功從回調中成功sendResponse,那麼您應該也可以從錯誤回調中獲得。
  • 創建一個長期生活的端口long-living connections可讓您隨時向內容腳本發佈消息。

我還想認爲你可以調用從一個完全獨立的功能sendResponse如果存儲sendResponse功能,因此,它是對錯誤處理程序訪問,但也許你已經證明,已經假(會愛看到你的代碼)。文檔使得聽起來就像請求被打開,直到響應。

+0

你是對的,使用$ .ajax()讓我們指定一個錯誤回調函數;但它可能比我簡單的XHR函數稍微複雜一些。此外,爲什麼我在後臺腳本中包含jQuery的唯一原因就是爲此;用我自己的XHR函數,我甚至不需要在後臺頁面中使用jQuery。 – Bambax 2010-11-17 15:38:24

0

看代碼,看看我是否可以提取它的一些建設工作示例(響應SERG評論),我不認爲我想要做的是可能後與jQuery。

在jQuery中,當一個AJAX調用失敗,錯誤事件被稱爲(爲它由.ajaxError()事件處理程序捕獲),然後函數結束/回報。當.ajaxError()處理程序運行時,該函數因此死掉。 (我相信,這是JS中異步事件系統的重點)。

現在,我只是猜測這裏,但我認爲,在Chrome中,內容腳本和後臺腳本之間的通信信道時監聽功能已經用完關閉;在偵聽器函數結束後,不能將響應從後臺腳本發送到內容腳本,這正是我在處理事件處理程序中的ajax錯誤時所要做的。

所以,我最終做的是重新實現一個實際發回完整對象的ajax函數:如果調用失敗,它將返回出現錯誤的事實以及錯誤代碼,以便調用者函數(實際上是一個回調函數)可以處理它併發送回內容腳本的響應。

這是隻有幾行,和(我認爲)是通用,所以在這裏它是:

function xhr(url, callback) { 
    var req = new XMLHttpRequest(); 
    req.open("GET", url, true); 
    req.onreadystatechange = function() { 
     if (req.readyState == 4) { 
      var resp = { 
       "url": url, 
       "status": req.status 
       }; 
      if (req.status == 200) { 
       resp.html = req.responseText; 
       resp.outcome = "ok"; 
       } 
      else { 
       resp.outcome = "error"; 
       } 
      callback(resp); 
      } 
     } 
    req.send(null); 
    }