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

Chrome Manifest V3扩展content.js中chrome.offscreen未定义问题求助

Chrome扩展Manifest V3中content.js无法访问chrome.offscreen的解决方法

问题重现

开发Chrome扩展时,尝试在content.js中调用chrome.offscreen.createDocument播放音频,控制台抛出错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'createDocument')
    at checkForVideoElement (content.js:28:30)
    at MutationObserver.<anonymous> (VM304 content.js:7:21)

排查后确认chrome.offscreen对象未定义,即使已在manifest.json中声明offscreen权限。

核心原因

Content Script运行在网页的隔离上下文里,Manifest V3明确规定:chrome.offscreen API仅支持在Service Worker(background)、Popup、Options页面这类扩展自身的上下文环境中调用,Content Script没有权限访问该API。

解决方案

调整逻辑,通过"Content Script → Background Service Worker → Offscreen页面"的消息传递流程实现音频播放:

  1. Content.js检测到视频元素后,向Background发送播放请求
  2. Background负责创建Offscreen文档,并向Offscreen发送播放指令
  3. Offscreen页面执行音频播放逻辑

修改后的代码

1. content.js(修改消息发送逻辑)

// Try to find the video element immediately
if (!checkForVideoElement()) {
    // If not found, use a mutation observer to watch for changes
    const observer = new MutationObserver((mutationsList, observer) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                if (checkForVideoElement()) {
                    // Stop observing once the video element is found
                    observer.disconnect();
                    break;
                }
            }
        }
    });

    // Start observing the document body for added nodes
    observer.observe(document.body, { childList: true, subtree: true });
}

function checkForVideoElement() {
    var video = document.querySelector("video");
    if (video) {
        console.log(video);

        if (video.currentTime <= 60) {
            console.log("Video found less than 60s");
            // 改为向Background发送播放请求
            chrome.runtime.sendMessage({action: "requestPlaySound"});
        }

        return true;
    }
    return false;
}

2. background.js(新增Offscreen创建与消息转发逻辑)

// 监听来自Content Script的消息
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
    if (message.action === "requestPlaySound") {
        await createOffscreenDocument();
        // 向Offscreen页面发送播放指令
        chrome.runtime.sendMessage({action: "playSound"});
    }
});

// 封装Offscreen文档创建逻辑,避免重复创建
async function createOffscreenDocument() {
    if (await chrome.offscreen.hasDocument()) {
        return;
    }
    await chrome.offscreen.createDocument({
        url: chrome.runtime.getURL("offscreen.html"),
        reasons: ["AUDIO_PLAYBACK"],
        justification: "Playing Custom Sound for Netflix video"
    });
}

3. offscreen.js(保持原有逻辑即可)

console.log("Offscreen script loaded");

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log("Offscreen script received message:", message);

    if (message.action === "playSound") {
        playSound();
    }
});

function playSound() {
    chrome.storage.local.get("Sound", function (result) {
        let audio = result.Sound;
        if (audio) {
            console.log("Audio found");
            // Convert the data URI to a Blob
            fetch(audio)
                .then(response => response.blob())
                .then(blob => {
                    const audioUrl = URL.createObjectURL(blob);
                    const audioElement = new Audio(audioUrl);
                    audioElement.play().then(() => {
                        console.log("Audio played successfully");
                    }).catch(error => {
                        console.error("Error playing audio:", error);
                    });
                })
                .catch(error => {
                    console.error("Error converting audio data:", error);
                });
        } else {
            console.log("Audio not found");
        }
    });
}

注意事项

  • 确保offscreen.html的路径正确,无需在manifest中额外声明,只要能通过chrome.runtime.getURL访问即可
  • 修改代码后需重新加载扩展,确保manifest权限和脚本变更生效
  • 重复创建Offscreen文档会报错,因此在Background中加入hasDocument检查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:37:21