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

Chrome扩展网站拦截功能开发问题求助(附Manifest及background.js代码)

Chrome网站拦截扩展修复方案

问题分析

你的代码存在三个核心问题导致功能失效:

  • 监听仅执行一次:chrome.tabs.query仅在后台脚本启动时获取一次当前激活标签的URL,后续用户切换页面或打开新标签时,拦截规则不会更新。
  • URL匹配格式错误:chrome.webRequest.onBeforeRequest的urls参数要求是匹配模式数组,你传入的单个具体URL无法正确匹配该域名下的所有请求,且格式不符合API要求。
  • 无动态更新机制:没有提供用户自定义拦截列表的入口,也没有监听拦截规则的变化来更新拦截逻辑。

基础修复(快速验证功能)

如果只是想先验证拦截功能正常,可修改background.js为以下代码,拦截指定域名(示例为example.com):

// 定义要拦截的网站匹配模式数组
const blockedSites = [
  "*://*.example.com/*",
  "*://example.com/*"
];

// 添加拦截监听
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    return { cancel: true };
  },
  { urls: blockedSites },
  ["blocking"]
);

同时确保manifest.json的权限正确(你的权限已经满足,无需修改)。

完整动态拦截方案(支持用户自定义)

如果需要实现用户可添加/移除拦截网站的功能,可按以下步骤修改:

1. 更新manifest.json,添加弹出页面权限

{
  "name": "Loki",
  "manifest_version": 2,
  "description": "这是为格鲁吉亚测试安全上网创建的扩展",
  "version": "0.1",
  "permissions": ["webRequest", "webRequestBlocking", "<all_urls>", "tabs", "storage"],
  "background": {
    "scripts": ["background.js"]
  },
  "browser_action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/logo_16x16.png",
      "48": "icons/logo_48x48.png",
      "128": "icons/logo_128x128.png"
    }
  },
  "icons": {
    "16": "icons/logo_16x16.png",
    "48": "icons/logo_48x48.png",
    "128": "icons/logo_128x128.png"
  }
}

2. 创建popup.html(用户交互界面)

<!DOCTYPE html>
<html>
<head>
  <style>
    body { width: 250px; padding: 15px; }
    .input-group { margin-bottom: 10px; }
    button { width: 100%; padding: 8px; }
    #blockedList { margin-top: 15px; }
  </style>
</head>
<body>
  <div class="input-group">
    <input type="text" id="siteInput" placeholder="输入要拦截的域名(如example.com)">
  </div>
  <button id="addBtn">添加拦截</button>
  <div id="blockedList"></div>

  <script src="popup.js"></script>
</body>
</html>

3. 创建popup.js(处理用户交互与存储)

// 加载已拦截的网站列表
document.addEventListener('DOMContentLoaded', () => {
  chrome.storage.local.get('blockedSites', (result) => {
    const blockedSites = result.blockedSites || [];
    renderBlockedList(blockedSites);
  });

  // 添加拦截按钮事件
  document.getElementById('addBtn').addEventListener('click', () => {
    const input = document.getElementById('siteInput');
    const site = input.value.trim();
    if (!site) return;

    // 转换为匹配模式
    const pattern = `*://*.${site}/*`;
    const patternWithoutWww = `*://${site}/*`;

    chrome.storage.local.get('blockedSites', (result) => {
      const blockedSites = result.blockedSites || [];
      // 避免重复添加
      if (!blockedSites.includes(pattern) && !blockedSites.includes(patternWithoutWww)) {
        blockedSites.push(pattern);
        blockedSites.push(patternWithoutWww);
        chrome.storage.local.set({ blockedSites }, () => {
          renderBlockedList(blockedSites);
          input.value = '';
          // 通知后台更新拦截规则
          chrome.runtime.sendMessage({ action: 'updateBlockedSites' });
        });
      }
    });
  });
});

// 渲染拦截列表
function renderBlockedList(sites) {
  const listEl = document.getElementById('blockedList');
  listEl.innerHTML = '';
  sites.forEach((site, index) => {
    // 提取域名展示
    const domain = site.replace(/\*:\/\/\*\./, '').replace(/\/\*/, '');
    if (domain === '') return;

    const item = document.createElement('div');
    item.style.marginBottom = '5px';
    item.textContent = domain;
    const removeBtn = document.createElement('button');
    removeBtn.textContent = '移除';
    removeBtn.style.marginLeft = '10px';
    removeBtn.style.padding = '2px 6px';
    removeBtn.addEventListener('click', () => {
      chrome.storage.local.get('blockedSites', (result) => {
        const blockedSites = result.blockedSites.filter(s => s !== site && s !== `*://${domain}/*`);
        chrome.storage.local.set({ blockedSites }, () => {
          renderBlockedList(blockedSites);
          chrome.runtime.sendMessage({ action: 'updateBlockedSites' });
        });
      });
    });
    item.appendChild(removeBtn);
    listEl.appendChild(item);
  });
}

4. 修改background.js(动态更新拦截规则)

let currentListener = null;

// 初始化拦截规则
function initBlocking() {
  chrome.storage.local.get('blockedSites', (result) => {
    const blockedSites = result.blockedSites || [];
    updateBlockingListener(blockedSites);
  });
}

// 更新拦截监听
function updateBlockingListener(blockedSites) {
  // 移除旧的监听
  if (currentListener) {
    chrome.webRequest.onBeforeRequest.removeListener(currentListener);
  }

  // 添加新的监听
  if (blockedSites.length > 0) {
    currentListener = function(details) {
      return { cancel: true };
    };
    chrome.webRequest.onBeforeRequest.addListener(
      currentListener,
      { urls: blockedSites },
      ["blocking"]
    );
  } else {
    currentListener = null;
  }
}

// 监听来自弹出页面的更新请求
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'updateBlockedSites') {
    initBlocking();
  }
});

// 启动时初始化
initBlocking();

注意事项

  • 由于你使用的是Manifest V2,Chrome 88及以上版本仍支持,但未来会被Manifest V3替代。如果需要适配V3,需将webRequest替换为declarativeNetRequest API。
  • 测试时需在Chrome扩展管理页面开启「开发者模式」,加载已解压的扩展文件夹。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:30:54