Chrome扩展MV3:如何监听declarativeNetRequest请求拦截并实时更新拦截数?
Chrome MV3 实时更新拦截请求数的解决方案
核心方案:监听declarativeNetRequest.onRuleMatched事件
MV3中没有直接的onRequestBlocked事件,但可以通过监听规则匹配事件实时捕获请求被拦截的时机,以此调用API更新计数,完全符合MV3轻量化service worker的设计,无需让后台持续运行。
实现步骤
- 配置Manifest权限
在manifest.json中声明必要的权限和规则资源:
{ "manifest_version": 3, "name": "请求拦截计数器", "version": "1.0", "permissions": ["declarativeNetRequest", "tabs", "storage"], "host_permissions": ["<all_urls>"], "background": { "service_worker": "service-worker.js" }, "action": { "default_icon": "icon.png" }, "declarative_net_request": { "rule_resources": [ { "id": "block_rules", "enabled": true, "path": "rules.json" } ] } }
- 编写拦截规则
创建rules.json定义需要拦截的请求规则(示例为拦截广告域名):
[ { "id": 1, "priority": 1, "action": { "type": "block" }, "condition": { "urlFilter": "*://*.ad.com/*", "resourceTypes": ["script", "image", "stylesheet"] } } ]
- 在Service Worker中监听事件并更新计数
在service-worker.js中监听规则匹配事件,实时更新对应标签页的拦截计数,并同步到扩展图标徽章:
// 监听规则匹配(即请求被拦截)事件 chrome.declarativeNetRequest.onRuleMatched.addListener(async (details) => { const tabId = details.tabId; if (tabId === -1) return; // 忽略非标签页发起的请求(如扩展自身请求) // 从storage读取当前标签页的拦截计数 const storedData = await chrome.storage.local.get(`tab_${tabId}`); const currentCount = storedData[`tab_${tabId}`] || 0; const newCount = currentCount + 1; // 存储更新后的计数 await chrome.storage.local.set({ [`tab_${tabId}`]: newCount }); // 更新扩展图标徽章的数字 chrome.action.setBadgeText({ tabId: tabId, text: newCount.toString() }); // 若需配置徽章样式,可调用setOptions(对应你提到的setExtensionActionOptions) chrome.action.setOptions({ tabId: tabId, badgeBackgroundColor: '#e74c3c', badgeTextColor: '#ffffff' }); }); // 标签页关闭时清理对应计数,避免存储冗余 chrome.tabs.onRemoved.addListener(async (tabId) => { await chrome.storage.local.remove(`tab_${tabId}`); });
关键说明
- 该事件会在每次请求被拦截时实时触发,唤醒service worker完成计数更新后,service worker会自动休眠,完全符合MV3的性能优化要求。
- 使用
chrome.storage.local存储计数,避免service worker休眠后丢失数据,确保刷新页面或重新唤醒后台时计数准确。 - 过滤
tabId === -1的请求,避免统计非用户标签页的后台请求。
内容的提问来源于stack exchange,提问作者Serhii
相关产品推荐
相关产品推荐

