You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Google Chrome扩展开发求助:Service Worker注册失败与document未定义错误排查

问题根源与解决方案

Let's break down exactly what's going wrong here and fix it step by step:

Why You're Seeing These Errors

  1. "Service Worker registration failed" & "Uncaught ReferenceError: document is not defined":
    Manifest V3's Service Workers (your background.js) run in a DOM-less background context—they have no access to document, window, or any webpage DOM elements. You tried to run DOM manipulation code directly in the service worker, which is impossible.
    To make it worse, you accidentally assigned the same background.js to both the service worker and content scripts section in your manifest, mixing two completely different execution environments.

Step-by-Step Fix

1. Clean Up Your Manifest.json

First, separate your service worker and content script roles. Create a dedicated content script for DOM manipulation, and keep the service worker for background-only logic (if you need it).

Here's the corrected manifest:

{
  "name": "blah",
  "description": "blah",
  "version": "1.0",
  "manifest_version": 3,
  "icons": {
    "16": "icon.png",
    "32": "icon.png",
    "48": "icon.png",
    "128": "icon.png"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "minimum_chrome_version": "93",
  // Keep background.js only for service worker tasks (remove if you don't need background logic)
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"], // Use a dedicated content script for DOM work
    "css": [] // Remove popup.css here—it's for your popup, not webpages
  }],
  "permissions": [ "storage", "activeTab", "scripting" ],
  "host_permissions": [ "<all_urls>" ],
  "web_accessible_resources": [ {
    "resources": ["ezgif-3-9576363471.gif"],
    "matches": ["<all_urls>"]
  } ]
}

2. Create a Dedicated Content Script (content.js)

Move all your DOM manipulation code here—content scripts run directly inside the webpage's context, so they have full access to document:

// content.js - runs inside the user's active webpage
const img = document.createElement("img");
img.src = chrome.runtime.getURL("ezgif-3-9576363471.gif");

// Add optional styles to prevent breaking the webpage layout
img.style.position = "fixed";
img.style.bottom = "20px";
img.style.right = "20px";
img.style.zIndex = "9999";
img.style.width = "150px";

document.body.appendChild(img);

3. Fix Your Service Worker (background.js)

If you need background logic (like listening for extension installation or tab changes), keep it here—but only code that doesn't touch the DOM:

// background.js - service worker (DOM-less context)
chrome.runtime.onInstalled.addListener(() => {
  console.log("Extension installed successfully!");
});

// Add other background-only logic here (no document/window allowed)

Alternative: Inject Image On Popup Click (More Flexible)

If you don't want the image to automatically load on every page, you can trigger it via your popup instead. Here's how:

  1. Remove the content_scripts section from your manifest.
  2. Add a button to popup.html:
    <button id="insertImgBtn">Insert Image</button>
    <script src="popup.js"></script>
    
  3. Create popup.js to handle the click and inject the script:
    document.getElementById("insertImgBtn").addEventListener("click", async () => {
      const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
      
      await chrome.scripting.executeScript({
        target: { tabId: activeTab.id },
        func: () => {
          const img = document.createElement("img");
          img.src = chrome.runtime.getURL("ezgif-3-9576363471.gif");
          img.style.position = "fixed";
          img.style.bottom = "20px";
          img.style.right = "20px";
          img.style.zIndex = "9999";
          document.body.appendChild(img);
        }
      });
    });
    

Key Takeaways for Manifest V3

  • Service Workers: Background-only, no DOM access—use for event listening, data storage, or cross-tab communication.
  • Content Scripts: Run inside webpages, full DOM access—use for modifying page content.
  • Web Accessible Resources: Always declare assets like images if you need to load them in content scripts or injected code.

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

火山引擎 最新活动