51

这似乎是一个难题(或不可能??)。我想在观看 Chrome 扩展后台脚本下获取并阅读由浏览器中的 HTTP 请求引起的 HTTP 响应。我们可以通过这种方式获取 HTTP Request Body

chrome.webRequest.onBeforeRequest.addListener(function(data){
    // data contains request_body
},{'urls':[]},['requestBody']);

我还检查了这些 stackoverflows

有什么聪明的方法可以在 Chrome 扩展中获取 HTTP 响应正文吗?

4

5 回答 5

31

我找不到比这个 anwser 更好的方法。

用于读取 HTTP 响应的 Chrome 扩展程序

答案告诉如何获取 响应标头并显示在另一个页面中。但是响应 obj 中没有正文信息(请参阅event-responseReceived)。如果您想在没有其他页面的情况下获取响应正文 ,请尝试此操作。

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)来关闭丑陋的小费。

对不起,也许没有帮助... ^ ^

于 2015-04-24T10:34:24.723 回答
9

现在在 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.
      }
}
});
});
于 2019-10-11T18:30:10.267 回答
7

这绝对不是 Chrome 扩展生态系统开箱即用的东西。但是,我可以找到几种方法来解决这个问题,但它们都有自己的缺点。

一种方法是:

  1. 使用内容脚本来注入我们自己的自定义脚本。
  2. 使用自定义脚本扩展 XHR 的本机方法以读取响应。
  3. display: none将响应添加到隐藏(非)元素内的网页 DOM 。
  4. 使用内容脚本读取隐藏的响应。

第二种方法是创建一个DevTools 扩展,它是唯一提供 API 来读取每个请求的扩展。

我在这里的博客文章中详细记录了这两种方法

如果您遇到任何问题,请告诉我!:)

于 2018-12-11T07:02:19.917 回答
1

要获得 XHR响应正文,您可以按照此答案中的说明进行操作。

要获得 FETCH响应正文,您可以查看本文中的解决方案 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()

于 2022-02-07T01:51:10.687 回答
0

如果可以提供帮助,我会展示我完成的代码。我添加了下划线以获取请求 url,谢谢

//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 但参数不同的请求。如:

第二个不会得到正确的 responseBody,它会显示:

Chrome Extension: "Unchecked runtime.lastError: {"code":-32000,"message":"No resource with given identifier found"}

但是我直接在后台devtools中调试,它得到了第二个正确的身体。

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 不是完美的解决方案,有人可以提供帮助吗?谢谢。

于 2021-10-18T02:39:14.690 回答