这似乎是一个难题(或者不可能??)。 我想在观看 Chrome 扩展后台脚本时获取并读取由浏览器中的 HTTP 请求引起的 HTTP 响应。 我们可以通过这种方式获取HTTP Request Body
chrome.webRequest.onBeforeRequest.addListener(function(data){
// data contains request_body
},{'urls':[]},['requestBody']);
我还检查了这些 stackoverflows
有什么聪明的方法可以在 Chrome 扩展中获取 HTTP 响应正文吗?
我找不到比这个答案更好的方法了。
答案告诉我们如何获取响应标题并显示在另一个页面中。但是响应对象中没有正文信息(请参阅event-responseReceived)。如果您想在没有其他页面的情况下获得响应body,请尝试此操作。
var currentTab;
var version = "1.0";
chrome.tabs.query( //get current Tab
{
currentWindow: true,
active: true
},
function(tabArray) {
currentTab = tabArray[0];
chrome.debugger.attach({ //debug at current tab
tabId: currentTab.id
}, version, onAttach.bind(null, currentTab.id));
}
)
function onAttach(tabId) {
chrome.debugger.sendCommand({ //first enable the Network
tabId: tabId
}, "Network.enable");
chrome.debugger.onEvent.addListener(allEventHandler);
}
function allEventHandler(debuggeeId, message, params) {
if (currentTab.id != debuggeeId.tabId) {
return;
}
if (message == "Network.responseReceived") { //response return
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
}, function(response) {
// you get the response body here!
// you can close the debugger tips by:
chrome.debugger.detach(debuggeeId);
});
}
}
我认为它对我来说足够有用,你可以使用
chrome.debugger.detach(debuggeeId)
来关闭丑陋的提示。
抱歉,也许没有帮助... ^ ^
现在 Chrome 开发者工具扩展中有一种方法,示例代码可以在这里看到:博客文章。
简而言之,这是他的示例代码的改编版:
chrome.devtools.network.onRequestFinished.addListener(request => {
request.getContent((body) => {
if (request.request && request.request.url) {
if (request.request.url.includes('facebook.com')) {
//continue with custom code
var bodyObj = JSON.parse(body);//etc.
}
}
});
});
response 正文,您可以按照此答案中的说明进行操作。
要获取 FETCHresponse 正文,您可以检查本文中的解决方案 3 以及此答案。两者都获得响应正文而不使用 chrome.debugger。
简而言之,您需要使用与 XHR 请求相同的方法将以下函数从内容脚本注入到页面中。
const constantMock = window.fetch;
window.fetch = function() {
return new Promise((resolve, reject) => {
constantMock.apply(this, arguments)
.then((response) => {
if (response) {
response.clone().json() //the response body is a readablestream, which can only be read once. That's why we make a clone here and work with the clone
.then( (json) => {
console.log(json);
//Do whatever you want with the json
resolve(response);
})
.catch((error) => {
console.log(error);
reject(response);
})
}
else {
console.log(arguments);
console.log('Undefined Response!');
reject(response);
}
})
.catch((error) => {
console.log(error);
reject(response);
})
})
}
如果 response.clone().json() 不起作用,您可以尝试 response.clone().text()
//background.js
import _, { map } from 'underscore';
var currentTab;
var version = "1.0";
chrome.tabs.onActivated.addListener(activeTab => {
currentTab&&chrome.debugger.detach({tabId:currentTab.tabId});
currentTab = activeTab;
chrome.debugger.attach({ //debug at current tab
tabId: currentTab.tabId
}, version, onAttach.bind(null, currentTab.tabId));
});
function onAttach(tabId) {
chrome.debugger.sendCommand({ //first enable the Network
tabId: tabId
}, "Network.enable");
chrome.debugger.onEvent.addListener(allEventHandler);
}
function allEventHandler(debuggeeId, message, params) {
if (currentTab.tabId !== debuggeeId.tabId) {
return;
}
if (message === "Network.responseReceived") { //response return
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
//use underscore to add callback a more argument, passing params down to callback
}, _.partial(function(response,params) {
// you get the response body here!
console.log(response.body,params.response.url);
// you can close the debugger tips by:
// chrome.debugger.detach(debuggeeId);
},_,params));
}
}
我还发现 chrome.debugger.sendCommand 中有一个错误。如果我有两个具有相同 URI 但参数不同的请求。如:
Chrome Extension: "Unchecked runtime.lastError: {"code":-32000,"message":"No resource with given identifier found"}
但是我直接在后台开发工具中调试,它得到了第二个正确的主体。
chrome.debugger.sendCommand({tabId:2},"Network.getResponseBody",{requestId:"6932.574"},function(response){console.log(response.body)})
所以tabId和requestId没有问题。
然后我用 setTimeout 包装 chrome.debugger.sendCommand,它将正确获取第一个和第二个responseBody。
if (message === "Network.responseReceived") { //response return
console.log(params.response.url,debuggeeId.tabId,params.requestId)
setTimeout(()=>{
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
//use underscore to add callback a more argument, passing params down to callback
}, _.partial(function(response,params,debuggeeId) {
// you get the response body here!
console.log(response.body,params.response.url);
// you can close the debugger tips by:
// chrome.debugger.detach(debuggeeId);
},_,params,debuggeeId));
},800)
}
我认为 setTimeout 不是完美的解决方案,有人可以提供帮助吗?
谢谢。