如何在Manifest V3 Chrome扩展中检测自定义协议请求
拦截Manifest V3扩展中的自定义协议请求
Chrome的webRequest API确实仅支持官方文档列出的标准协议,自定义协议(如internal://)不在其拦截范围内,这就是你的代码无法触发的原因。要捕获这类请求,需要从页面上下文入手,拦截发起请求的行为,具体方案如下:
实现步骤
1. 配置Manifest.json
在扩展配置中添加内容脚本,确保脚本在页面加载初期注入(覆盖页面原生方法):
{ "manifest_version": 3, "name": "自定义协议拦截工具", "version": "1.0", "content_scripts": [ { "matches": ["*://目标网站域名/*"], // 替换为实际目标网站的匹配规则 "js": ["content.js"], "run_at": "document_start" // 关键:在页面脚本执行前注入 } ], "permissions": ["runtime"] }
2. 编写内容脚本(content.js)
在页面上下文里重写各类请求发起方法,拦截自定义协议:
// 拦截location.href赋值 const originalHrefSetter = Object.getOwnPropertyDescriptor(window.location.__proto__, 'href').set; Object.defineProperty(window.location.__proto__, 'href', { set: function(value) { if (value.startsWith('internal://')) { // 向后台发送拦截到的URL chrome.runtime.sendMessage({ type: 'customProtocol', url: value }); return; // 阻止默认跳转行为 } originalHrefSetter.call(this, value); } }); // 拦截window.open调用 const originalOpen = window.open; window.open = function(url) { if (url?.startsWith('internal://')) { chrome.runtime.sendMessage({ type: 'customProtocol', url: url }); return null; // 阻止打开新窗口 } return originalOpen.apply(this, arguments); }; // 拦截<a>标签跳转 document.addEventListener('click', e => { const link = e.target.closest('a'); if (link?.href.startsWith('internal://')) { e.preventDefault(); chrome.runtime.sendMessage({ type: 'customProtocol', url: link.href }); } }); // 拦截fetch请求 const originalFetch = window.fetch; window.fetch = function(resource) { const url = typeof resource === 'string' ? resource : resource.url; if (url?.startsWith('internal://')) { chrome.runtime.sendMessage({ type: 'customProtocol', url: url }); return Promise.reject(new Error('自定义协议请求已拦截')); } return originalFetch.apply(this, arguments); }; // 拦截XMLHttpRequest请求 const originalXHR = XMLHttpRequest; XMLHttpRequest = function() { const xhr = new originalXHR(); const originalOpen = xhr.open; xhr.open = function(method, url) { if (url?.startsWith('internal://')) { chrome.runtime.sendMessage({ type: 'customProtocol', url: url }); this.abort(); // 终止XHR请求 return; } originalOpen.apply(this, arguments); }; return xhr; };
3. 后台脚本接收拦截信息
在后台脚本(如background.js)中监听内容脚本发送的消息,处理拦截到的URL:
chrome.runtime.onMessage.addListener((message, sender) => { if (message.type === 'customProtocol') { console.log('捕获到自定义协议请求:', message.url); // 在这里添加你的业务逻辑 } });
关键注意事项
run_at: "document_start"必须设置,确保内容脚本在页面原生脚本执行前加载,保证重写的方法生效。- 根据目标网站的实际请求方式,选择性保留上述拦截逻辑(比如如果确认没有fetch/XHR请求,可以去掉对应部分)。
内容的提问来源于stack exchange,提问作者nikitakot
相关产品推荐
相关产品推荐

