”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 如何修复 Chrome 扩展程序中孤立内容脚本导致的“扩展程序上下文无效”错误?

如何修复 Chrome 扩展程序中孤立内容脚本导致的“扩展程序上下文无效”错误?

发布于2024-11-08
浏览:337

How to Fix \

如何在 Chrome 扩展程序更新后删除孤立脚本

问题

无意中重新加载 Chrome 扩展程序,尤其是处于开发者模式的扩展程序,可能会创建孤立内容脚本。这些脚本仍然在后台运行,但与扩展的其余部分失去了通信,从而导致诸如“扩展上下文无效”和“未检查的运行时.lastError”之类的错误。

解决方案

孤立的内容脚本仍然可以接收 DOM 消息。删除它:

1.从新内容脚本发送消息:

  • 在新的工作内容脚本中,使用 window.dispatchEvent 向孤立脚本发送消息。
  • 使用唯一消息标识符,例如 orphanMessageId.

2。在孤立脚本中取消注册侦听器:

  • 在孤立脚本中,为 orphanMessageId 定义侦听器。
  • 在此侦听器中,取消注册所有先前侦听器并取消全局变量。
  • 这使得旧脚本符合垃圾回收条件。

3.后台脚本:

  • 在扩展重新加载/安装时重新注入内容脚本。

4。内容脚本:

  • 为事件侦听器使用命名函数以保留其引用。
  • 设置 window.running 属性以指示活动实例。
  • 收到 orphanMessageId 时,取消注册侦听器并将脚本标记为孤立的。

5.弹出脚本:

  • 在发送消息之前检查是否存在工作内容脚本。
  • 利用ensureContentScript确保脚本注入。

例子Code:

background.js:

// Re-inject content script
chrome.runtime.onInstalled.addListener(() => {
  chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
    chrome.tabs.executeScript(tabs[0].id, { file: 'content.js' });
  });
});

content.js:

// Orphaned script detection and cleanup
var orphanMessageId = chrome.runtime.id   'orphanCheck';
window.dispatchEvent(new Event(orphanMessageId));
window.addEventListener(orphanMessageId, unregisterOrphan);

// Register named listeners
chrome.runtime.onMessage.addListener(onMessage);
document.addEventListener('mousemove', onMouseMove);

// Orphan flag and cleanup function
window.running = true;

function unregisterOrphan() {
  if (chrome.runtime.id) {
    // Not orphaned
    return;
  }
  window.removeEventListener(orphanMessageId, unregisterOrphan);
  document.removeEventListener('mousemove', onMouseMove);
  try {
    chrome.runtime.onMessage.removeListener(onMessage);
  } catch (e) {}
  return true;
}

popup.js:

async function sendMessage(data) {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  if (await ensureContentScript(tab.id)) {
    return await chrome.tabs.sendMessage(tab.id, data);
  }
}

async function ensureContentScript(tabId) {
  try {
    const [{ result }] = await chrome.scripting.executeScript({
      target: { tabId },
      func: () => window.running === true,
    });
    if (!result) {
      await chrome.scripting.executeScript({
        target: { tabId },
        files: ['content.js'],
      });
    }
    return true;
  } catch (e) {}
}
最新教程 更多>
  • 如何防止 Pandas 在保存 CSV 时添加索引列?
    如何防止 Pandas 在保存 CSV 时添加索引列?
    避免使用 Pandas 保存的 CSV 中的索引列使用 Pandas 进行修改后保存 csv 文件时,默认行为是包含索引列。为了避免这种情况,可以在使用 to_csv() 方法时将索引参数设置为 False。为了详细说明,请考虑以下命令序列:pd.read_csv('C:/Path/to/file....
    编程 发布于2024-11-08
  • 如何在没有 JavaScript 的情况下使用 POST 参数执行 PHP 重定向?
    如何在没有 JavaScript 的情况下使用 POST 参数执行 PHP 重定向?
    带 POST 参数的 PHP 重定向提出的查询涉及将用户从一个网页重定向到另一个网页,同时保留 POST 参数。原始方法涉及通过表单将 GET 参数传输到 POST 参数,该方法被认为不是最理想的,特别是对于禁用 JavaScript 的用户而言。该问题寻求一个纯基于 PHP 的解决方案,用于重定向...
    编程 发布于2024-11-08
  • 如何在 React 中访问提供者外部的上下文时处理错误
    如何在 React 中访问提供者外部的上下文时处理错误
    使用 React 的 Context API 时,处理组件尝试访问 Provider 外部上下文的情况非常重要。如果不这样做,可能会导致意想不到的结果或难以跟踪的错误。 问题 当您使用 createContext() 创建上下文时,您可以选择传递默认值。如果组件尝试访问提供程序外部的上下文,则返回此...
    编程 发布于2024-11-08
  • Filament:删除记录时删除附件
    Filament:删除记录时删除附件
    Filament 允许您向记录添加附件,但在删除记录时不会删除附件。 为了解决这个问题,我们有两种选择: 监听模型删除事件 当模型即将被删除时,它会触发删除事件。我们可以监听此事件来触发负责在模型不再存在之前删除任何附件的功能。 在模型类中,我们可以添加 booted 方法来向模型注...
    编程 发布于2024-11-08
  • 如何在信用记录检索中实现左连接?
    如何在信用记录检索中实现左连接?
    How to Perform Left Joins in Doctrine在函数 getHistory() 中,您尝试检索用户的信用历史记录。但是,连接子句中的初始语法导致了错误。要在 Doctrine 中执行左连接,可以使用以下语法:$qb ->select('a', 'u') ...
    编程 发布于2024-11-08
  • 以下是几种可能的标题:

1. How to Make CSS Transitions Work with `ngIf` in Angular 2? 
2. Why Does `ngIf` Break My CSS Transitions in Angular 2?
3. Angular 2: Combining `ngIf` and CSS Animations for Smooth Trans
    以下是几种可能的标题: 1. How to Make CSS Transitions Work with `ngIf` in Angular 2? 2. Why Does `ngIf` Break My CSS Transitions in Angular 2? 3. Angular 2: Combining `ngIf` and CSS Animations for Smooth Trans
    Angular 2 的 ngIf 和 CSS 过渡/动画如何在 Angular 2 中使用 CSS 将 div 从右侧滑入?<div class="note" [ngClass]="{'transition':show}" *ngIf="sho...
    编程 发布于2024-11-08
  • 如何使您的 React 应用程序更快:性能提示和最佳实践
    如何使您的 React 应用程序更快:性能提示和最佳实践
    啊,反应!我们喜爱的用于构建 UI 的库。它就像一剂神奇的药剂,让我们的网络应用程序感觉具有交互性和快速性——直到有一天,它却没有了。突然,你注意到事情变慢了。点击按钮就像用信鸽寄信一样。您的应用程序从闪电般的速度变成了慢吞吞的速度,用户开始给您“看”。 但是别担心!就像咖啡可以解决大部分生活问题一...
    编程 发布于2024-11-08
  • 带有 go 工作区的 Golang 微服务模块化架构
    带有 go 工作区的 Golang 微服务模块化架构
    可扩展的代码库基础设施 Golang 在后端开发、并发操作方面表现出色,是构建可扩展和高性能后端应用程序的完美套件。由于缺乏围绕 Go 工作区的微服务架构的帖子,这是通过不同服务共享模块化代码的令人难以置信的工具,我决定分享我的实现。 项目设置 mkdir dock...
    编程 发布于2024-11-08
  • 如何在 C++0x 中使用初始化列表初始化成员数组?
    如何在 C++0x 中使用初始化列表初始化成员数组?
    使用初始值设定项列表初始化成员数组在 C 0x 中,尝试使用初始值设定项列表初始化成员数组时,可能会遇到错误“赋值中的类型不兼容” .要解决此问题,请考虑使用可变参数模板构造函数:struct foo { int x[2]; template <typename... T>...
    编程 发布于2024-11-08
  • 如何在 AWS Lambda 函数中导入 Pandas(库) - AWS Lambda Layers
    如何在 AWS Lambda 函数中导入 Pandas(库) - AWS Lambda Layers
    假设您需要在 AWS Lambda 函数上运行 Python 脚本,然后收到此错误? { "errorMessage": "Unable to import module 'lambda_function': No module named 'pandas', "errorType": "R...
    编程 发布于2024-11-08
  • 将日期与 MySQL 的 DATE_FORMAT 进行比较时,为什么使用相同的格式至关重要?
    将日期与 MySQL 的 DATE_FORMAT 进行比较时,为什么使用相同的格式至关重要?
    与 MySQL DATE_FORMAT 进行日期比较使用 MySQL 的 DATE_FORMAT 函数比较日期时,了解您选择的格式会影响比较结果至关重要.在给定的示例中,表包含格式为“%d-%m-%Y”的日期,并且查询尝试使用相同的格式来比较它们。但是,这会导致不正确的结果,因为“28-10-201...
    编程 发布于2024-11-08
  • 如何在Android中实现带有按钮的自定义操作栏?
    如何在Android中实现带有按钮的自定义操作栏?
    在 Android 中实现带有自定义按钮的自定义操作栏创建自定义 ActionBar 可以实现应用程序用户界面的个性化,提供视觉一致性和增强的用户体验。本指南将讨论三个关键方面:1。创建自定义操作栏视图要在 ActionBar 中合并自定义视图,请按照下列步骤操作:扩充自定义布局: 创建自定义操作栏...
    编程 发布于2024-11-08
  • 相同的 Python 字符串何时以及为何共享或具有单独的内存分配?
    相同的 Python 字符串何时以及为何共享或具有单独的内存分配?
    Python 的字符串内存分配之谜Python 字符串表现出一种奇怪的行为,即相同的字符串可以共享内存或单独存储。了解这种行为对于优化 Python 程序中的内存消耗至关重要。字符串初始化和比较最初,具有相同字符的两个字符串(例如 a == b)通常共享内存,如下所示由它们相同的 id 值证明。然而...
    编程 发布于2024-11-08
  • 了解 PHP OOP 中的访问修饰符:公共、受保护和私有
    了解 PHP OOP 中的访问修饰符:公共、受保护和私有
    在 PHP 面向对象编程 (OOP) 中,访问修饰符控制类属性和方法的可见性。 PHP 中的主要访问修饰符是 public、protected 和 private。 本文将引导您了解这些访问修饰符的目的和用法,并解释如何在 PHP OOP 中有效地应用它们。 1.公共访问修饰符 关键...
    编程 发布于2024-11-08
  • 如何在Python中建立跨模块变量可访问性:共享变量而不共享实例?
    如何在Python中建立跨模块变量可访问性:共享变量而不共享实例?
    建立跨模块变量可访问性在Python中,一个方便的跨模块变量是__debug__。然而,创建具有类似功能的自定义变量可能看起来具有挑战性。本文深入研究这个主题,探索一种跨模块定义共享变量同时保持其不变性的方法。解决方案:利用全局模块级变量建立如果跨模块变量不共享公共变量实例,请考虑使用全局模块级变量...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3