You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展Manifest V3中chrome.scripting.executeScript失效问题

Chrome扩展Manifest V3中chrome.scripting.executeScript不执行问题修复

问题根源

点击弹窗按钮跳转页面后,Chrome扩展的popup会自动关闭,导致popup内的脚本上下文被销毁。虽然tabs.onUpdated回调里的alert('a')可能因事件队列残留触发,但后续的chrome.scripting.executeScript调用会因为popup已销毁而无法正常注入脚本到目标页面。手动刷新后再次点击按钮时,popup是在目标页面已加载的状态下运行,不会因页面跳转被关闭,所以API能正常工作。

修复方案:迁移逻辑到Service Worker

将页面跳转、脚本注入的核心逻辑移至Service Worker(后台脚本),它不会随popup关闭而终止,能稳定完成后续操作。

1. 更新manifest.json

添加background配置,指定后台脚本文件:

{
    "name": "Scraper",
    "description": "Simple Extension to Scrape Websites, and Push Them to ConnectionSphere for Data Enrichment",
    "version": "2.0",
    "permissions": ["storage", "webRequest", "scripting", "declarativeContent", "activeTab", "tabs", "downloads", "*://*/*", "http://connectionsphere.com:80/*", "http://connectionsphere.com/api1.0/emails/verify.json"],
    "host_permissions": [ "https://www.amazon.com/*", "https://connectionsphere.com/*", "https://github.com/*" ],
    "manifest_version": 3,
    "icons": {
      "48": "/48.png",
      "128": "/128.png"
    },
    "action": {
        "default_popup": "popup.html",
        "default_icon": {
            "48": "/48.png",
            "128": "/128.png"
        }
    },
    "background": {
        "service_worker": "background.js"
    }
}

2. 创建background.js

编写后台逻辑,接收popup的消息并处理页面跳转与脚本注入:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.action === 'scrapePage') {
        const pageUrl = message.url;
        chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
            const tabId = tabs[0].id;
            chrome.tabs.update(tabId, {url: pageUrl}, () => {
                // 监听页面加载完成事件
                const loadListener = (updatedTabId, changeInfo) => {
                    if (updatedTabId === tabId && changeInfo.status === 'complete') {
                        chrome.tabs.onUpdated.removeListener(loadListener);
                        // 注入脚本到目标页面
                        chrome.scripting.executeScript({
                            target: {tabId: tabId, allFrames: true},
                            func: () => {
                                alert('b');
                                document.body.innerHTML = 'hola';
                                return document.title;
                            }
                        }, (injectionResults) => {
                            if (injectionResults?.length) {
                                // 将结果回传给popup
                                chrome.runtime.sendMessage({result: injectionResults[0].result});
                            }
                        });
                    }
                };
                chrome.tabs.onUpdated.addListener(loadListener);
            });
        });
        return true; // 保持消息通道开放,支持异步响应
    }
});

3. 修改popup.js

简化popup逻辑,仅负责发送消息到后台并接收结果:

'use strict';

const text = document.getElementById('text');
const startBtn = document.getElementById('start');

startBtn.onclick = function() {
    const pageUrl = 'https://github.com/';
    text.innerHTML = 'Scraping page...';
    // 向后台发送任务消息
    chrome.runtime.sendMessage({action: 'scrapePage', url: pageUrl}, (response) => {
        if (response?.result) {
            text.innerHTML = response.result;
        }
    });
};

额外说明

  • 原代码中chrome.tabs.onUpdated的监听时机存在风险:在chrome.tabs.update之后添加监听,可能错过页面更新事件。迁移到后台后,在tabs.update的回调内添加监听,能确保捕获到目标页面的加载完成状态。
  • 通过func参数注入的函数会被序列化后传入目标页面,函数内部不能引用popup或后台的外部变量,需确保逻辑独立。

内容的提问来源于stack exchange,提问作者LeandroS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:40:19