如何在Chrome扩展中获取并重发指定XHR请求(含请求头)
在Chrome扩展中捕获并重发指定XHR请求的实现方案
1. 配置扩展权限(manifest.json)
首先在扩展的manifest.json中声明必要权限,确保能监听网络请求并访问目标站点:
{ "manifest_version": 3, "name": "捕获并重发Typing请求", "version": "1.0", "permissions": ["webRequest", "storage", "activeTab"], "host_permissions": ["<all_urls>"], // 建议替换为目标站点域名,比如"https://example.com/*" "background": { "service_worker": "background.js" }, "action": { "default_popup": "popup.html" } }
webRequest:用于监听网络请求生命周期storage:临时存储捕获到的请求信息activeTab:确保能访问当前标签页的请求上下文host_permissions:指定监听的站点范围,缩小范围可提升安全性
2. 监听并捕获目标请求(background.js)
在后台服务worker中监听XHR请求,筛选出名为typing的请求(这里假设请求URL包含typing关键词,可根据实际请求特征调整过滤条件),并保存请求的关键信息:
let capturedRequest = null; // 监听请求头,获取URL、请求方法和请求头 chrome.webRequest.onBeforeSendHeaders.addListener( (details) => { // 筛选目标XHR请求:类型为XMLHttpRequest,且URL包含typing if (details.type === "xmlhttprequest" && details.url.includes("typing")) { capturedRequest = { requestId: details.requestId, url: details.url, method: details.method, headers: details.requestHeaders }; } }, { urls: ["<all_urls>"] }, ["requestHeaders", "extraHeaders"] ); // 监听请求体(如果原请求有POST/PUT等带体的请求) chrome.webRequest.onBeforeRequest.addListener( (details) => { if (capturedRequest && details.requestId === capturedRequest.requestId) { if (details.requestBody) { // 解析请求体为字符串 const body = details.requestBody.raw ? new TextDecoder().decode(details.requestBody.raw[0].bytes) : details.requestBody.formData; capturedRequest.body = body; } } }, { urls: ["<all_urls>"] }, ["requestBody"] ); // 给popup提供获取捕获请求的接口 chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === "getCapturedRequest") { sendResponse(capturedRequest); } });
注意:如果目标请求的“名称”不是通过URL识别,而是DevTools中显示的自定义请求名称,可通过initiator(请求发起页面的URL)或其他请求特征进一步筛选,需根据实际请求详情调整判断逻辑。
3. 实现重发请求的UI与逻辑(popup.html + popup.js)
创建popup页面,添加按钮触发重发操作,调用fetch还原并发送请求:
popup.html
<!DOCTYPE html> <html> <head> <style> button { padding: 8px 16px; cursor: pointer; margin: 10px; } </style> </head> <body> <button id="reSendBtn">重发Typing请求</button> <script src="popup.js"></script> </body> </html>
popup.js
document.getElementById("reSendBtn").addEventListener("click", async () => { // 从background获取捕获的请求信息 const capturedRequest = await chrome.runtime.sendMessage({ type: "getCapturedRequest" }); if (!capturedRequest) { alert("未捕获到目标请求"); return; } try { // 构造fetch请求,还原原请求参数 const response = await fetch(capturedRequest.url, { method: capturedRequest.method, headers: new Headers(capturedRequest.headers), body: capturedRequest.body || undefined, credentials: "include" // 携带Cookie等凭证,根据原请求调整 }); // 处理并展示响应 const responseData = await response.text(); alert(`重发成功,响应内容:\n${responseData}`); } catch (error) { alert(`重发失败:${error.message}`); } });
关键注意事项
- 部分请求头(如
Host、Origin)浏览器会自动处理,无需手动设置,强行设置可能导致请求失败 - 如果原请求包含签名、时间戳等校验参数,重发时需保持原参数一致,否则会被服务器拒绝
- 测试时需确保扩展已加载到Chrome中,且目标页面已触发过
typing请求
内容的提问来源于stack exchange,提问作者Giorgoua20009
相关产品推荐
相关产品推荐

