Chrome Extension V3中chrome.webRequest无法获取requestBody的问题
问题原因及解决方案
核心原因
Chrome 扩展的webRequest.onBeforeRequest API无法捕获流式传输的请求体,而Dropbox的put_block上传请求正好属于这类场景,因此会返回{error: 'Unknown error.'}。
具体细节
- 流式请求体限制:当请求采用
Transfer-Encoding: chunked(分块编码)或流媒体形式传输时,Chrome无法在onBeforeRequest阶段读取完整请求体——此时数据还在传输过程中,并未全部到达浏览器,API自然无法提供有效内容。Dropbox上传图片(尤其是大文件)时会自动启用分块上传,完全符合这个触发条件。 - API阶段局限性:
onBeforeRequest是请求发送前的钩子,对于流式上传,浏览器还未接收完整的请求体(甚至可能刚启动传输);而Network面板能看到payload是因为它是在请求完成后捕获的完整数据,两者的时机完全不同。
可行解决方案
方案1:从页面侧监听上传事件
放弃通过webRequest捕获请求体,改用content script在页面中监听文件上传的源头事件:
// content.js document.addEventListener('change', (e) => { if (e.target.type !== 'file' || !e.target.files.length) return; // 获取选中的文件基础信息 const file = e.target.files[0]; console.log('选中文件:', file.name, file.size, file.type); // 拦截XMLHttpRequest监听上传行为 const originalXHR = XMLHttpRequest; window.XMLHttpRequest = function() { const xhr = new originalXHR(); xhr.upload.addEventListener('progress', (evt) => { if (evt.target?.url.includes('put_block')) { console.log('上传进度:', (evt.loaded/evt.total*100).toFixed(2)+'%'); // 如需关联文件内容,可结合之前获取的file对象做后续处理 } }); return xhr; }; // 拦截fetch监听上传行为(如果页面使用fetch上传) const originalFetch = fetch; window.fetch = async (url, options) => { if (url.includes('put_block') && options?.body instanceof File) { console.log('上传文件:', options.body.name); } return originalFetch(url, options); }; });
方案2:改用declarativeNetRequest(仅适用于规则匹配)
如果只是需要拦截或标记这类请求,而非获取具体内容,可以用declarativeNetRequest替代webRequest——它性能更好且没有流式请求的限制,但无法读取请求体内容。
配置权限提醒
确保扩展manifest.json中已正确声明所需权限:
{ "permissions": ["webRequest", "<all_urls>", "activeTab"], "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ] }
内容的提问来源于stack exchange,提问作者Salmin Skenderovic
相关产品推荐
相关产品推荐

