端口错误:无法建立连接。接收端不存在。在Chromium

时间:2012-02-02 02:51:40

标签: google-chrome-extension

我正在开发Chrome中的扩展程序,但是存在问题。在我的inject.js中,我提出了如下请求:

chrome.extension.sendRequest({command:'skip'},callback)

在我的`background.js中,我只是添加一个请求监听器,如:

chrome.extension.onrequest.addListener(function(req,sender,res){console.log("procession"})

但是有一个错误:

端口错误:无法建立连接。接收端不存在

这似乎是Chrome中的一个错误? PS:
我的manifest.json

的一部分
"background": {
    "scripts": ["background.js"]
  },
  "content_scripts": [
    {
      "matches": ["&lt all_urls &gt"], 
      "js": ["inject.js"]
    }
  ],

我在Chromium 17,我尝试重新加载扩展程序,重新打开浏览器......没有发生任何事情 有人得到一些想法吗?

16 个答案:

答案 0 :(得分:22)

这并不总是原因,但如果您background.js中有错误,请检查以下链接:

Inspect views: _generated_background_page.html

在“扩展程序”页面中,它会显示任何JavaScript错误。

这阻止了我的联系建立。

答案 1 :(得分:14)

问题可能是 sendRequest() onRequest 已弃用并替换为sendMessage()onMessage 。自从最近的Chrome 20更新以来,它们似乎完全消失了。

关于Message Passing的官方文档甚至不再提及 sendRequest()

这是一个记录变化的链接:http://codereview.chromium.org/9965005/

答案 2 :(得分:9)

我发现自己遇到了与此处描述的问题相同的问题。我发现适用于我的解决方案是使用backgroundpage而不是后台脚本,如下所示:

"background_page": "src/background.html",
  // maybe this seems to work instead of background { scripts [] }

  /* this gives a Port error: Could not ...
  "background": {
  "scripts": ["src/background.js"]
  },
  */

我希望这也适合你。

答案 3 :(得分:5)

在Windows 7上的Chrome 20.0.1132.57 m中,HTML背景页无效,但错误相同:

Port error: Could not establish connection. Receiving end does not exist. miscellaneous_bindings:232

我尝试使用包含以下内容的background.js脚本:

chrome.extension.onConnect.addListener(function(port) {
    port.onMessage.addListener(function(msg) {
        // May be empty.
    });
});

解决了我的内容脚本中的直接onDisconnect

port = chrome.extension.connect();
port.onDisconnect.addListener(function (event) {
    // Happened immediately before adding the proper backend setup.
    // With proper backend setup, allows to determine the extension being disabled or unloaded.
});

正确的代码来自Chromium Extensions消息传递示例: http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/messaging/timer/page.js?view=markup

该示例还包含第二部分,作为sendRequest的后端,但我自己没有测试过:

chrome.extension.onRequest.addListener(
    function(request, sender, sendResponse) {
        // Don't know if it may be empty or a sendResponse call is required.
    });

答案 4 :(得分:2)

经过一段时间的调查后,我发现了问题。

我也得到了:

Port error: Could not establish connection. Receiving end does not exist. 

在解释之前,我想说我正在使用 sendMessage onMessage 进行沟通。

对我来说,当我从后台页面向我的内容脚本运行的一个标签发送消息时,会出现此错误。

我的扩展程序仅在youtube打开的标签上运行。 因此,当我更改某些偏好时,我正在查看我打开了哪些标签并发送消息以更新更新的首选项。

在正常情况下,它工作正常,但如果我打开了youtube的n(n> = 1)个标签页。我点击“重新加载”按钮进行扩展,我更改了一些内容... youtube标签没有刷新,它们丢失了消息监听器,所以我收到了这个错误。

这似乎很正常。

如果我在扩展重新加载后刷新youtube选项卡,则不会出现此错误。

我找到了一个解决方案,它可能不适用于所有情况:

当我遇到这个问题时,我的代码是:

chrome.tabs.sendMessage(tabId, {proprName: proprName, newValue: newValue}, function(response) {});

现在我的代码是:

chrome.tabs.sendMessage(tabId, {proprName: proprName, newValue: newValue});

对于我,我不需要响应回调,因为没有响应,我有这个错误。

答案 5 :(得分:2)

我正在使用 sendMessage onMessage 进行通信,在我的工作流程中,我首先将来自inject.js的消息发送到我的background.js,我也得到了“端口错误:无法建立连接。接收端不存在。”错误。

所以我决定处理使用响应功能(如ACK),如果背景没有响应,我会继续尝试使用setTimeout。

// background.js

...
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
...
//some code

sendResponse({status: 'everything ok'})
return true;    
});

// injected.js

var myInjectedFunctionality = function() {

    chrome.extension.sendMessage({method: "Steroids:loadScripts"}, function(res) {
        if(res && res.status) {
            } else {
                setTimeout(myInjectedFunctionality, 3000);
            }
    });
};
myInjectedFunctionality();

我的代码现在正常运行,所以我认为解释很容易查看。 Chrome在你想要的页面中注入你的代码时不会准备Background.js和连接东西,所以没有人听你发送的消息,所以如果没有人在听,就像我一样继续尝试。

答案 6 :(得分:2)

此处的其他一些答案具有很好的调试建议或一小部分难题,但是,如果您想像我一样注入(第三方)网页,则此处没有答案列出正确的答案组件。

共有4个步骤:

  • 一个外部后台监听器
  • 前台消息发件人,
  • 为消息发送者注入扩展ID
  • 和清单中的规则将所有内容链接在一起。

下面的示例应为您注入js所需的所有条件,该js将消息从google.com上的任何页面发送到您自己的扩展程序

首先在 manifest.json 中,添加described here的消息传递规则:

"externally_connectable": {
    "matches": ["*://*.google.com/*"]
}

然后,在您的后台脚本或页面中,您需要一个外部侦听器不是常规chrome.runtime.onMessage。 msot答案中已经提到的addListener),这是described here

chrome.runtime.onMessageExternal.addListener( (request, sender, sendResponse) => {
    console.log("Received message from " + sender + ": ", request);
    sendResponse({ received: true }); //respond however you like
});

一旦拥有了这些部分,就可以像平常一样使用消息发件人,但是将扩展ID 作为第一个参数:

chrome.runtime.sendMessage(myExtId, { /* whatever you want to send goes here */ },
    response => {
         /* handle the response from background here */
    }
);

如果您不知道如何获取用作第一个参数的外部ID,可以如下所示插入扩展ID 。这是必需的,因为 chrome.runtime.id @@@ extension_id 都无法在注入的脚本中工作:

//create a script tag to inject, then set a variable with the id in that script
let idScript = document.createElement("script");
idScript.setAttribute("type", "application/javascript");
idScript.textContent = 'var myExtId = "' + chrome.runtime.id +'";';
let parent = ( document.head || document.documentElement );
parent.insertBefore( idScript, parent.firstChild );

//inject and run your other script here

idScript.remove(); //then cleanup 

因为我们将其设置为 var ,所以其他脚本现在可以直接访问该值

答案 7 :(得分:1)

尝试将一些竞争脚本注入一个标签,其中网址为 chrome:// * https://chrome.google.com/* ,当连接这些时背景页面中的标签

例如

chrome.tabs.connect(tab.id).postMessage(msg)

然后将抛出

Port error: Could not establish connection. Receiving end does not exist.

这些页面不允许注入内容脚本,连接将立即断开连接。

所以,检查网址并不连接这些标签,然后不抛出异常

答案 8 :(得分:1)

查看最新手册: http://developer.chrome.com/extensions/messaging.html

  

注意:如果多个页面正在侦听onMessage事件,则只有   首先为特定事件调用sendResponse()将成功   发送回复。对该事件的所有其他回复都将是   忽略。

关闭标签页,只留一页,然后检查。就我而言,这就是问题所在。

答案 9 :(得分:1)

现在面对同样的问题。

//这是我以前的 background.js

chrome.runtime.onInstalled.addListener(function () {
  //some other code here
  chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
    if (message.url) {
        chrome.downloads.download({
            url: message.url,
            conflictAction: 'uniquify',
            saveAs: false
        });
    }
});});//(Sorry, I tried but failed to put the last bracket on next line)

你知道,当onInstalled事件发生时, chrome.runtime.onMessage.addListener 被触发,当我把它从这个范围中取出时,我的代码就像这样:

chrome.runtime.onInstalled.addListener(function () {
  //some other code here
});  
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
    if (message.url) {
        chrome.downloads.download({
            url: message.url,
            conflictAction: 'uniquify',
            saveAs: false
        });
    }
});

现在效果很好。希望对你有所帮助。

答案 10 :(得分:1)

我使用manifest_version: 2chrome.runtime.sendMessage看到了这个错误。我从网页连接到扩展程序,而不是在扩展程序中。

解决方案是确保我在manifest.json中的externally_connectable.matches数组中有正确的值。您需要列出您希望能够连接到扩展程序的URL。请参阅Play's recommendations for contexts

答案 11 :(得分:0)

如果您遇到问题,主要是因为您引用了过时的文档,请更新它!

访问:chrome extension: messaging.html

答案 12 :(得分:0)

我看到了这个问题,我的内容脚本没有加载,因此发布消息从未发生过。

问题原因是我打开了后台脚本检查器并且只是推送Cmd + R(刷新),但我的manifest.json中有一个错误。当我真正进入扩展页面并重新加载该页面时,我收到了显示清单错误的警报。

基本上,我看到了这个,因为我的内容脚本从未加载过,我认为我刷新了我的清单,但我不是。

答案 13 :(得分:0)

对于清单2.0和sendMessage而言,它相当简单:

如果您尝试在弹出窗口中使用sendMessage且在后台脚本末尾没有设置侦听器或以某种方式删除了该侦听器,则会发生这种情况。

我是指听众-chrome.runtime.onMessage.addListener

答案 14 :(得分:0)

我将内容脚本中的chrome.runtime.sendMessagechrome.runtime.onMessage.addEventListener放在window.onload或自执行功能中,它可以正常工作。 在清单中,我使用

"background": { "scripts": ["background.js"], "persistent": false },

清单版本:2。 希望对您有所帮助。

答案 15 :(得分:0)

我遇到了这个问题,因为我在background.js中添加了一个侦听器,当它被调用时,它将向弹出页面发送消息以更新视图状态。尽管有时会调用侦听器,但实际上并不存在弹出页面。在发送消息之前,我检查以确保弹出页面存在,并避免出现此问题。

相关问题