Webextension内联安装chrome.runtime.connect问题

时间:2017-08-24 09:36:24

标签: javascript google-chrome google-chrome-extension

我有一个非常奇怪的问题,我开发了一个使用内容脚本和后台脚本(使用chrome.runtime.connect)和nativemessaging之间的消息传递的webextension。

我面临的问题是,当我安装扩展程序(事先从商店手动然后连接到我的网站,一切正常工作,chrome.runtime.connect工作并返回一个有效的端口到背景脚本。

但是,当我从我的网站进行内联安装扩展以解决事实,必须导航到网页中有内容脚本时,我手动将内容脚本注入我的页面

 function injectContentScript() {
             var s = document.createElement("script");
             s.setAttribute("src", "chrome-extension://<extensionid>/content.js");
             document.head.appendChild(s);
         }

和完全相同的内容脚本但手动注入的行为并不相同。 chrome.runtime.connect返回一个null对象,chrome.runtime.lastError给我

  

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

我正在呼叫发送方(content.js - 手动注入的内容脚本)chrome.runtime.connect(extensionID)其中,扩展ID是chrome webstore生成的扩展的ID。并在接收方(background.js - 扩展背景脚本)chrome.runtime.onConnect.addListener(onPortConnected);

我不确定如何调试此问题,也许这是一个时间问题? 即使使用内联安装(我已添加日志并通过chrome扩展管理器中的background.html对其进行调试),后台脚本也能很好地执行

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:3)

您有两种情况。

  1. 您的内容脚本content.js在导航时正常执行,作为清单中定义的内容脚本。

    在这种情况下,它在附加到页面的特殊JS上下文中执行,并为内容脚本保留。有关说明,请参阅Execution Environment文档部分。它与网页隔离,被视为扩展的一部分(尽管权限较低)。

    从内容脚本连接时,chrome.runtime.connect()被视为扩展部分之间的内部通信。因此,虽然您可以提供扩展ID,但不需要它。

    更重要的是,在这种情况下提出的事件是chrome.runtime.onConnect

  2. 你想要的&#34;立即注入内容脚本&#34;从网页调用的代码完全不同。

    而不是创建新的执行上下文,而是将代码直接添加到页面中;它被视为扩展程序的一部分,无权访问扩展API。

    通常,对chrome.runtime.connect()的调用会失败,因为这不是暴露给网页的功能;但是,您还声明了externally_connectable,因此它会将专门公开到您的网页。

    在这种情况下,为connect传递扩展名ID为必需。你已经这样做了,所以电话就成功了。

    然而,这是导致其失败的原因:相应的事件不再是onConnect,而是onConnectExternal

  3. 应该做的是:

    • 不混合在非常不同的上下文中运行的代码。

    • 如果您需要从网页到背景的通信,请始终从网页进行,有时不从内容 - 有时从页面进行。

      这样你只需要听onConnectExternal,它就不再需要内容脚本(如果它是唯一的功能)。

      请参阅文档:Sending messages from web pages

    • 您不必从chrome-extension://<extensionid>/获取代码;您可以直接将其添加到您网站的代码中,并可能避免使用web_accessible_resources

    如果您确实想要在首次运行时注入内容脚本,请参阅示例this answer

    相关阅读:How to properly handle chrome extension updates from content scripts