【问题标题】:Firefox webextension Error: Could not establish connection. Receiving end does not existFirefox webextension 错误:无法建立连接。接收端不存在
【发布时间】:2017-06-21 10:31:42
【问题描述】:

我正在尝试将变量从后台脚本发送到与 HTML 页面关联的内容脚本。内容脚本使用从后台脚本接收的变量更新 HTML 内容。

问题是我收到此错误消息:

Error: Could not establish connection. Receiving end does not exist.

后台脚本main.js:

var target = "<all_urls>";
function logError(responseDetails) {
  errorTab = responseDetails.tabId;
  console.log("Error tab: "+errorTab);

  errorURL = responseDetails.url;
  console.log("Error URL: "+errorURL);

  //send errorURL variable to content script
  var sending = browser.tabs.sendMessage(errorTab, {url: errorURL})
    .then(response => {
      console.log("Message from the content script:");
      console.log(response.response);
    }).catch(onError);

  //direct to HTML page
  browser.tabs.update(errorTab,{url: "data/error.html"});
}//end function

browser.webRequest.onErrorOccurred.addListener(
  logError,
  {urls: [target],
  types: ["main_frame"]}
);

error.html 是:

<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
  The error received is <span id="error-id"></span>
  <script src="content-script.js"></script>
</body>
</html>

content-script.js:

//listen to errorURL from the background script.
browser.runtime.onMessage.addListener(request => {
  console.log("Message from the background script:");
  console.log(request.url);
  return Promise.resolve({response: "url received"});
}); //end onMessage.addListener

//update the HTML <span> tag with the error
document.getElementById("error-id").innerHTML = request.url;

manifest.json:

{
  "manifest_version": 2,
  "name": "test",
  "version": "1.0",
  "background": {
    "scripts": ["main.js"]
  },

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["webextension/data/content-script.js"]
    }
  ],

  "permissions": [
    "<all_urls>",
    "activeTab",
    "tabs",
    "storage",
    "webRequest"
  ]
}

【问题讨论】:

    标签: javascript firefox firefox-addon firefox-addon-webextensions


    【解决方案1】:

    你得到错误:

    Error: Could not establish connection. Receiving end does not exist.
    

    当您尝试与内容脚本未侦听消息的选项卡进行通信(例如tabs.sendMessage()tabs.connect())时。这包括选项卡中不存在内容脚本的时间。

    您不能将内容脚本注入到about:* URL 中

    对于您的问题,您收到此错误是因为标签中没有注入任何内容脚本。当您尝试发送消息时,在 main_frame webRequest.onErrorOccurred 事件中,选项卡的 URL 已经是 about:neterror?[much more, including the URL where the error occurred]。您不能将内容脚本注入about:* URL。因此,选项卡中没有内容脚本正在侦听您的消息。

    具体来说,您在 manifest.json content_scripts 条目中使用了 &lt;all_urls&gt; match pattern&lt;all_urls&gt; 匹配:

    特殊值 "&lt;all_urls&gt;" 匹配任何受支持方案下的所有 URL:即“http”、“https”、“file”、“ftp”、“app”。

    它确实匹配about:* URL。

    有关 Firefox 在 main_frame 中获取 webRequest.onErrorOccurred 事件时使用的 URL 的更多讨论,请参阅“Injecting into navigation error page gets: Error: No window matching {“matchesHost”:[“”]}

    【讨论】:

    • 是否有任何替代方案可以实现自定义错误页面,以便我将从后台脚本获得的错误 ID 发送到我的 HTML 内容脚本?我可以使用自定义的 HTML 更新选项卡内容。此 HTML 包含内容脚本。一些功能确实有效(比如听按钮点击),但我需要将错误数据发送到我的 HTML。我能做什么?
    • @user6875880,正如我在其他地方提到的,您不能在源自扩展程序的 HTML 页面中运行内容脚本。您可以通过使用 HTML &lt;script&gt; 标记将其包含在页面中来运行普通 JavaScript。此类脚本存在于后台上下文中。如果您想从后台脚本与该脚本进行通信,那么您可以使用我在中描述的任何方法:Communicate between scripts in the background context (background script, browser action, page action, options page, etc.)
    • 这就是我正在做的。如果您查看我的 HTML,我有 src="content-script.js"。所以,我需要做的就是从清单内容脚本中删除它?然后,我可以将错误代码从后台发送到 HTML 的脚本吗(HTML 使用 browser.tabs.update(errorTab,{url: "data/error.html"}); 显示在错误选项卡中??
    • 你当然应该从你的 manifest.json content_scripts 中删除它。但是,如我提供的链接中所述,您需要使用runtime.sendMessage()(用于后台上下文中的目的地)而不是tabs.sendMessage()(用于作为内容脚本的目的地)。但是,考虑到在您调用 tabs.update() 与 HTML 页面和 JavaScript 实际加载并运行之间存在延迟,您可能需要使用一种方法来将数据拉入 HTML 页面,而不是从后台页面推送到那里。
    • 谢谢。参考您上次的回复:you will probably want to use one of the methods which allows you to pull the data into the HTML page, rather than push it there from the background page。你能指定允许我提取数据的方法吗?或链接为一个例子左右。抱歉,我没明白你的意思。
    【解决方案2】:

    对于扩展程序开发人员:如果您重新加载扩展程序(作为开发循环的正常部分)它将切断与内容脚本的所有连接

    您必须记住还要重新加载页面,以便内容脚本重新正确收听。

    【讨论】:

      【解决方案3】:

      我也有同样的错误。

      我的问题和解决方案有所不同,但我会添加它以防万一。

      就我而言,我的 content.js 脚本最初没有 browser.runtime.onMessage.addListener() 函数 (FireFox)。

      当我后来将此侦听器添加到 content.js 脚本时,我没有在 FireFox 的“about:debugging”页面中重新加载临时扩展。我收到了上述错误。

      点击“about:debugging”选项卡中的“reload”后,内容脚本会收到消息。

      【讨论】:

        【解决方案4】:

        我决定用下一个方法完成同样的任务:

        我在制作上下文菜单时遇到了类似的问题。

        browser.contextMenus.onClicked.addListener((info, tab) => {
               if (info.menuItemId === "mymenu") {
               // some code
               browser.tabs.sendMessage(tabs[0].id, {greeting: "Hi from background script"});
               }
                });
        

        我得到错误:

        无法建立连接。接收端不存在

        我添加了一个函数和一个监听器:

        browser.contextMenus.onClicked.addListener((info, tab) => {
               if (info.menuItemId === "mymenu") {
               // some code
               browser.tabs.sendMessage(tabs[0].id, {greeting: "Hi from background script"});
               }
                });
           // -----function and Listener ------
           function connectToContent() {
              browser.tabs.query({ currentWindow: true, active: true
              }).then((tabs) => {
               browser.tabs.sendMessage(tabs[0].id, {greeting: "Activate Tab"});
               });
            }
        
            browser.tabs.onActivated.addListener(connectToContent);
        

        现在它正在工作。browser.tabs.onActivated.addListener 确实并保持连接。

        【讨论】:

          【解决方案5】:

          Firefox does not run content scripts on PDF pages 这意味着如果在 PDF 页面上执行扩展的后台脚本并尝试向内容脚本发送消息,它将失败并出现此错误。

          【讨论】:

            猜你喜欢
            • 2013-02-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-22
            • 2012-08-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多