首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >chrome.runtime.sendMessage在重新加载Chrome扩展后从内容脚本中抛出异常

chrome.runtime.sendMessage在重新加载Chrome扩展后从内容脚本中抛出异常
EN

Stack Overflow用户
提问于 2014-09-15 04:05:44
回答 1查看 5.3K关注 0票数 8

我将注入的内容脚本中的消息发送回Chrome扩展中的后台脚本,如下所示:

代码语言:javascript
运行
复制
chrome.runtime.sendMessage({action: "myResult"});

这很好,直到我重新加载我的扩展(通过设置->扩展-> "Reload (Ctrl+R)“作为我的扩展)。

反过来,当我的后台脚本启动时,它会多次调用chrome.tabs.executeScript (所有打开的选项卡)以编程方式重新注入我的内容脚本(as I showed in this question)。

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

错误:连接到扩展my_extension_id时出错

知道为什么会这样吗?

EN

Stack Overflow用户

回答已采纳

发布于 2014-09-15 08:45:30

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

  • 你给chrome.runtime.reload()打了电话。
  • 您已经在chrome://extensions/点击了Reload扩展。
  • 展期已经更新。

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

选项1:返回到仅使用内容脚本的功能

如果您的扩展可以在没有后台页面的情况下完美地工作,那么这可能是一个可以接受的解决方案。例如,如果您的内容脚本除了修改DOM和/或执行跨源请求之外,什么也不做。

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

代码语言:javascript
运行
复制
// 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插入内容脚本时设置一些事件来卸载以前的内容脚本。

代码语言:javascript
运行
复制
// 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();

请注意,任何知道事件名称的页面都会触发内容脚本的销毁。这是不可避免的,因为在扩展运行时被破坏之后,就没有适当的方法来安全地与扩展进行通信了。

票数 16
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25840674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档