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

Chrome扩展离线UI控制问题:webRequest API报错求助

解决Chrome扩展中webRequest报错及离线UI控制问题

首先,你遇到的TypeError: Cannot read property 'onErrorOccurred' of undefined错误,核心原因是内容脚本无法直接使用chrome.webRequestAPI——这个API属于扩展的核心权限范畴,只能在背景脚本(Service Worker 或 Background Page)中调用,内容脚本的权限受限,访问不到它。除此之外,你的代码还有几个语法和逻辑问题,我来逐个帮你修正:

问题拆解与修复步骤

1. 配置Manifest权限与背景脚本

首先要确保你的manifest.json(如果是Manifest V3)正确声明了所需权限和背景脚本:

{
  "manifest_version": 3,
  "name": "你的扩展名称",
  "version": "1.0",
  "permissions": ["webRequest", "activeTab"],
  "host_permissions": ["https://www.google.com/*"],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"], // 替换为你需要注入UI的页面匹配规则
      "js": ["content.js"]
    }
  ],
  "action": {
    "default_icon": {
      "16": "icon16.png" // 替换为你的图标路径
    }
  }
}

如果是Manifest V2,背景脚本的声明方式改为"background": {"scripts": ["background.js"]},权限配置逻辑一致。

2. 背景脚本中处理网络请求监听

把webRequest的监听逻辑移到background.js中,因为只有这里能调用该API。我们通过监听目标请求的成功/失败,向内容脚本发送状态消息:

const TARGET_URL = "https://www.google.com/searchdomaincheck?format=domain&type=chrome";

// 监听请求失败(模拟离线状态)
chrome.webRequest.onErrorOccurred.addListener(
  (details) => {
    if (details.url === TARGET_URL) {
      // 向当前活跃标签的内容脚本发送离线信号
      chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
        if (tabs[0]) chrome.tabs.sendMessage(tabs[0].id, {status: "offline"});
      });
    }
  },
  {urls: [TARGET_URL]}
);

// 监听请求成功完成
chrome.webRequest.onCompleted.addListener(
  (details) => {
    if (details.url === TARGET_URL) {
      chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
        if (tabs[0]) chrome.tabs.sendMessage(tabs[0].id, {status: "online"});
      });
    }
  },
  {urls: [TARGET_URL]}
);

这里要注意:

  • 不要直接在addListener里调用函数(比如showOffline()),要传递函数引用(不带括号),否则会立刻执行函数而不是作为回调触发。
  • 必须通过chrome.tabs.sendMessage和内容脚本通信,因为背景脚本无法直接操作页面DOM。

3. 内容脚本中处理UI状态

在内容脚本content.js里,我们需要正确获取DOM元素,并监听来自背景脚本的消息来控制UI显示:

let Canvas;

// 等待DOM加载完成后获取目标元素,避免元素未定义
document.addEventListener('DOMContentLoaded', () => {
  Canvas = document.getElementById('Canvas'); // 替换为你的Canvas元素选择器
});

// 监听背景脚本的消息
chrome.runtime.onMessage.addListener((message) => {
  if (!Canvas) return; // 元素未加载时跳过

  if (message.status === "offline") {
    showOffline();
  } else if (message.status === "online") {
    removeShowOffline();
  }
});

function showOffline() {
  Canvas.style.display = "none";
}

function removeShowOffline() {
  Canvas.style.display = "inline-grid";
}

这里修正了函数命名(符合JS小驼峰规范),并确保DOM加载完成后再获取元素,避免Canvas变量未定义。

4. 更简单的离线检测方案(可选)

如果你的需求只是检测浏览器是否在线,而非特定请求的失败,其实可以直接使用浏览器原生的navigator.onLineAPI,无需借助webRequest,代码更简洁:

document.addEventListener('DOMContentLoaded', () => {
  Canvas = document.getElementById('Canvas');
  // 初始化UI状态
  updateUI(navigator.onLine);
  // 监听在线/离线事件
  window.addEventListener('online', () => updateUI(true));
  window.addEventListener('offline', () => updateUI(false));
});

function updateUI(isOnline) {
  if (!Canvas) return;
  Canvas.style.display = isOnline ? "inline-grid" : "none";
}

这种方式更直接,不需要背景脚本参与,适合大多数离线检测场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:13