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替换为declarativeNetRequestAPI。 - 测试时需在Chrome扩展管理页面开启「开发者模式」,加载已解压的扩展文件夹。
内容的提问来源于stack exchange,提问作者saDpooro
相关产品推荐
相关产品推荐

