chrome.runtime.sendMessage 在重新加载 Chrome 扩展程序后从内容脚本中抛出异常 [英] chrome.runtime.sendMessage throws exception from content script after reloading Chrome Extension

查看:58
本文介绍了chrome.runtime.sendMessage 在重新加载 Chrome 扩展程序后从内容脚本中抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将来自注入的内容脚本的消息发送回我的 Chrome 扩展程序中的后台脚本:

I send messages from the injected content scripts back to my background script in my Chrome Extension as such:

chrome.runtime.sendMessage({action: "myResult"});

这很好用,直到我重新加载我的扩展程序(通过转到设置 -> 扩展程序 -> 为我的扩展程序重新加载(Ctrl + R)".)

This works fine, until I reload my extension (by going to Settings -> Extensions -> "Reload (Ctrl+R)" for my extension.)

反过来,当我的后台脚本启动时,它会为所有打开的标签重复调用chrome.tabs.executeScript,以编程方式重新注入我的内容脚本em>(正如我在这个问题中所展示的.)

In turn when my background script starts up it repeatedly calls chrome.tabs.executeScript for all open tabs to programmatically re-inject my content script (as I showed in this question.)

但是在我这样做之后,如果我从我的内容脚本中调用第一行sendMessage,它会抛出这个异常:

But after I do that, if I call that first sendMessage line from my content script, it throws this exception:

错误:连接扩展 my_extension_id 时出错

Error: Error connecting to extension my_extension_id

知道为什么会这样吗?

推荐答案

当扩展运行时被重新加载时,发生在以下任何一种情况下

When the extension runtime is reloaded, which happens in any of the following cases

  • 您调用了 chrome.runtime.reload().
  • 您在 chrome://extensions/ 上点击了重新加载扩展.
  • 扩展程序已更新.
  • You've called chrome.runtime.reload().
  • You've clicked on Reload extension at chrome://extensions/.
  • The extension was updated.

然后内容脚本中的大多数扩展 API 方法停止工作(包括导致问题中的错误的 chrome.runtime.sendMessage).有两种方法可以解决此问题.

then the most extension API methods in the content script cease to work (including chrome.runtime.sendMessage which causes the error in the question). There are two ways to work around this problem.

如果您的扩展程序可以在没有背景页面的情况下完美运行,那么这可能是一个可以接受的解决方案.例如.如果您的内容脚本除了修改 DOM 和/或执行跨域请求之外什么都不做.

If your extension can function perfectly without a background page, then this could be an acceptable solution. E.g. if your content script does nothing else besides modifying the DOM and/or performing cross-origin requests.

在从我的内容脚本调用任何 Chrome 扩展 API 之前,我在我的一个扩展程序中使用以下代码段来检测运行时是否仍然有效.

I'm using the following snippet in one of my extensions to detect whether the runtime is still valid before invoking any Chrome extension API from my content script.

// It turns out that getManifest() returns undefined when the runtime has been
// reload through chrome.runtime.reload() or after an update.
function isValidChromeRuntime() {
    // It turns out that chrome.runtime.getManifest() returns undefined when the
    // runtime has been reloaded.
    // Note: If this detection method ever fails, try to send a message using
    // chrome.runtime.sendMessage. It will throw an error upon failure.
    return chrome.runtime && !!chrome.runtime.getManifest();
}

// E.g.
if (isValidChromeRuntime()) {
    chrome.runtime.sendMessage( ... );
} else {
    // Fall back to contentscript-only behavior
}

选项 2:在内容脚本插入时卸载之前的内容脚本

当与后台页面的连接对您的内容脚本很重要时,您必须实施适当的卸载例程,并设置一些事件以在内容脚本执行时卸载先前的内容脚本通过 chrome.tabs.executeScript 插入.

Option 2: Unload the previous content script on content script insertion

When a connection with the background page is important to your content script, then you have to implement a proper unloading routine, and set up some events to unload the previous content script when the content script is inserted back via chrome.tabs.executeScript.

// Content script
function main() {
    // Set up content script
}

function destructor() {
    // Destruction is needed only once
    document.removeEventListener(destructionEvent, destructor);
    // Tear down content script: Unbind events, clear timers, restore DOM, etc.
}

var destructionEvent = 'destructmyextension_' + chrome.runtime.id;
// Unload previous content script if needed
document.dispatchEvent(new CustomEvent(destructionEvent));
document.addEventListener(destructionEvent, destructor);
main();

请注意,任何知道事件名称的页面都可能触发您的内容脚本的破坏.这是不可避免的,因为在扩展运行时被破坏后,将不再有适当的方法与扩展进行安全通信.

Note that any page that knows the name of the event can trigger destruction of your content script. This is unavoidable, because after the extension runtime is destroyed, there are no proper ways to securely communicate with the extension any more.

这篇关于chrome.runtime.sendMessage 在重新加载 Chrome 扩展程序后从内容脚本中抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆