如何在Chrome扩展中检测请求/响应体大小
解决方案
要准确获取所有请求(包括视频流)的请求/响应体大小,Chrome扩展的webRequest API提供了两个关键属性来替代不可靠的Content-Length响应头,同时可以通过监听请求阶段事件获取请求体大小:
核心思路
- 响应体大小:使用
onCompleted事件返回对象中的encodedDataLength(编码后实际传输的字节数)和decodedBodyLength(解码后的真实响应体大小),这两个值是Chrome内部统计的,不受分块传输(chunked)或服务器返回错误Content-Length的影响。 - 请求体大小:监听
onBeforeRequest事件,通过requestBody属性获取请求体的原始字节数据并计算总大小。
修改后的代码
首先确保你的manifest.json中声明了必要权限:
{ "manifest_version": 3, "name": "请求大小统计工具", "version": "1.0", "permissions": ["webRequest", "<all_urls>"], "background": { "service_worker": "background.js" } }
然后是background.js的代码:
// 监听请求发送前事件,获取请求体大小 const requestFilter = { urls: ["<all_urls>"] }; chrome.webRequest.onBeforeRequest.addListener( (request) => { let requestSize = 0; // 计算请求体总字节数 if (request.requestBody?.raw) { requestSize = request.requestBody.raw.reduce((total, chunk) => { return total + (chunk.bytes?.length || 0); }, 0); } // 存储请求ID对应的请求大小,后续和响应匹配 chrome.storage.session.set({ [`req_${request.requestId}`]: requestSize }); }, requestFilter, ["requestBody"] // 必须声明此参数才能获取requestBody ); // 监听请求完成事件,获取响应体大小并匹配请求大小 chrome.webRequest.onCompleted.addListener( async (request) => { // 取出对应请求的大小 const stored = await chrome.storage.session.get(`req_${request.requestId}`); const requestSize = stored[`req_${request.requestId}`] || 0; // 响应体的两个关键大小值 const encodedResponseSize = request.encodedDataLength; const decodedResponseSize = request.decodedBodyLength; console.log(`请求ID: ${request.requestId}`); console.log(`请求体大小: ${requestSize} 字节`); console.log(`编码后响应大小: ${encodedResponseSize} 字节`); console.log(`解码后响应大小: ${decodedResponseSize} 字节`); console.log(`请求URL: ${request.url}`); }, requestFilter, ["responseHeaders"] // 可选,不需要响应头可省略 );
关键说明
encodedDataLength:代表通过网络传输的响应数据字节数(包含gzip、deflate等编码压缩后的大小)。decodedBodyLength:代表解码后的响应体实际大小(即资源原始大小,比如视频文件的真实大小)。- 对于视频流这类分块传输的请求,
Content-Length响应头通常不存在或不准确,而上述两个属性会准确统计实际传输的总字节数。 - 使用
chrome.storage.session临时存储请求体大小,是因为onBeforeRequest和onCompleted事件通过requestId关联,会话存储适合这类短期数据存储。
内容的提问来源于stack exchange,提问作者Nefertem
相关产品推荐
相关产品推荐

