如何通过Chrome Debugger的Fetch API修改HTTP响应?
如何通过Chrome Debugger的Fetch API修改HTTP响应?
看起来你已经找对了方向,用Chrome DevTools Protocol的Fetch API确实能实现修改HTTP响应的需求,但你的代码里有几个小问题导致报错,我来帮你梳理并修正:
你的代码里的核心问题
- 调用
Fetch.getResponseBody时参数错误:你漏掉了第一个参数{ tabId },Chrome Debugger的sendCommand方法第一个参数必须是包含tabId的对象,这就是你看到TypeError: Error in invocation of debugger.sendCommand的直接原因。 - 未限制拦截范围:调用
Fetch.enable时没有指定请求匹配规则,会拦截所有请求,既影响性能也容易引发其他问题。 - 非目标请求处理不当:对于不匹配
example.com的请求,没必要去获取响应体再手动填充,直接让请求继续走原始流程更稳妥。 - 响应头格式问题:
fulfillRequest要求响应头是[{name: "...", value: "..."}]格式的数组,直接用params.responseHeaders可能会有格式不兼容的情况。
修正后的完整代码
let tabId; async function getTabs() { return new Promise((resolve) => { chrome.tabs.query({}, function (tabs) { resolve(tabs); }); }); } (async () => { let tabs = await getTabs(); let tab = tabs.filter(a => a.url.includes('example.com'))?.[0]; if (!tab) { console.log('没有找到包含example.com的标签页'); return; } tabId = tab.id; try { await new Promise((resolve, reject) => { chrome.debugger.attach({ tabId }, '1.3', (err) => { if (err) reject(err); else resolve(); }); }); // 只拦截目标域名的请求,减少不必要的拦截 await new Promise((resolve) => { chrome.debugger.sendCommand( { tabId }, 'Fetch.enable', { patterns: [ { urlPattern: 'https://example.com/*', requestStage: 'Response' } ] }, resolve ); }); chrome.debugger.onEvent.addListener(async (source, method, params) => { // 只处理请求暂停的事件,并且确保是当前标签页的事件 if (source.tabId !== tabId || method !== 'Fetch.requestPaused') return; const requestId = params.requestId; const isTargetRequest = params.request.url.startsWith('https://example.com/'); if (isTargetRequest) { // 获取原始响应体(注意处理base64编码) const responseBodyResult = await new Promise((resolve) => { chrome.debugger.sendCommand( { tabId }, 'Fetch.getResponseBody', { requestId }, resolve ); }); // 处理原始响应体的编码,如果是base64就解码,否则直接用 let originalBody = responseBodyResult.body; if (responseBodyResult.base64Encoded) { originalBody = atob(originalBody); } // 替换成自定义内容 const modifiedBody = 'modified body'; // 因为fulfillRequest要求body是base64编码的 const modifiedResponseBody = btoa(modifiedBody); // 准备响应头,确保格式正确 const responseHeaders = params.responseHeaders?.map(header => ({ name: header.name, value: header.value })) || []; // 填充修改后的响应 await new Promise((resolve) => { chrome.debugger.sendCommand( { tabId }, 'Fetch.fulfillRequest', { requestId, responseCode: 200, responseHeaders, body: modifiedResponseBody, base64Encoded: true }, resolve ); }); } else { // 非目标请求,直接继续原始响应流程 await new Promise((resolve) => { chrome.debugger.sendCommand( { tabId }, 'Fetch.continueRequest', { requestId }, resolve ); }); } }); } catch (err) { console.error('调试器附加失败:', err); } })();
关键修改说明
- 修复了
Fetch.getResponseBody的参数:补上了{ tabId }参数,解决了报错问题。 - 添加了请求拦截规则:在
Fetch.enable时指定了urlPattern,只拦截example.com下的请求,提升效率。 - 优化了非目标请求的处理:用
Fetch.continueRequest直接让请求走原始流程,避免不必要的响应体处理。 - 规范了响应头格式:把原始响应头转换成
fulfillRequest要求的数组格式,避免格式错误。 - 完善了编码处理:处理了响应体的base64编码和解码,确保修改后的内容能正确显示。
- 增加了错误处理:给
debugger.attach添加了错误捕获,避免标签页不存在或无法附加时崩溃。
备注:内容来源于stack exchange,提问作者丶 Limeー来夢 丶
相关产品推荐
相关产品推荐

