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

问题描述 投票:0回答:2

我有一个带有弹出页面的 Chrome 扩展,它通过简单的一次性请求将布尔变量传递到我的内容页面。然后,内容页面将根据从弹出页面传递的布尔变量的状态执行一些操作。这是完美的,直到我不小心删除了扩展(仍处于开发人员模式,扩展已解压)并不得不重新加载它。

这导致弹出检查控制台中出现“扩展上下文无效”错误,并且网页控制台似乎验证弹出页面和内容脚本未进行通信。启用 Chrome 扩展程序的网页显示此错误:Unchecked runtime.lastError: The message port returned before a response was returned.

根据我已经看到的一些答案,似乎重新加载我的 chrome 扩展程序已将我的原始工作内容脚本与扩展程序的其余部分“孤立”,这导致了上述“未检查的运行时.最后错误:消息端口在之前关闭”已收到答复。”网页控制台出现错误。

我相信我不能再次重新注入我的内容脚本,因为我的内容脚本具有 DOM 事件侦听器。有没有可能的方法来删除当前正在运行的孤立脚本?或者有什么建议可以解决这个问题吗?

这是我的 popup.js:

chrome.tabs.query({'active': true, 'currentWindow': true}, function (tabs) { chrome.tabs.sendMessage(tabs[0].id, {cTabSettings: (some boolean variable)}); });

这是我的内容.js:

// Listening for message from popup.js chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { if (request.cTabSettings === true) { enabled = true; } else if (request.cTabSettings === false) { enabled = false; } }); // DOM listener and action document.addEventListener('mousemove', function (e) { // Some action chrome.runtime.sendMessage({sender: "content", selText : "blah"}, function () { console.log("success"); }); }, false);

我正在使用 chrome 开发者模式版本 76。换句话来说,在我不小心重新加载它之前,这个 chrome 扩展

正在工作(内容脚本与弹出窗口通信)。

javascript google-chrome google-chrome-extension
2个回答
8
投票
由于孤立内容脚本仍然可以接收 DOM 消息,因此请通过

window

 将新工作内容脚本中的一条消息发送到幻影内容脚本。收到消息后,您将取消注册所有侦听器(并取消所有全局变量),这也将使您的旧脚本符合自动垃圾收集的条件。

背景.js:

请参阅

此示例中如何在重新加载/安装扩展时重新注入内容脚本。

内容.js:

var orphanMessageId = chrome.runtime.id + 'orphanCheck'; window.dispatchEvent(new Event(orphanMessageId)); window.addEventListener(orphanMessageId, unregisterOrphan); // register all listeners with named functions to preserve their object reference chrome.runtime.onMessage.addListener(onMessage); document.addEventListener('mousemove', onMouseMove); // the popup script checks it to see if a usable instance of content script is running window.running = true; function unregisterOrphan() { if (chrome.runtime.id) { // someone tried to kick us out but we're not orphaned! return; } window.removeEventListener(orphanMessageId, unregisterOrphan); document.removeEventListener('mousemove', onMouseMove); try { // 'try' is needed to avoid an exception being thrown in some cases chrome.runtime.onMessage.removeListener(onMessage); } catch (e) {} return true; } function onMessage(msg, sender, sendResponse) { //........... } function onMouseMove(event) { // DOM events still fire in the orphaned content script after the extension // was disabled/removed and before it's re-enabled or re-installed if (unregisterOrphan()) { return } //........... }
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) {} }
    

3
投票
请检查

这个答案

这不是删除脚本而是为了避免万一出错。

© www.soinside.com 2019 - 2024. All rights reserved.