简体   繁体   中英

Chrome Extension - How to get HTTP Response Body?

It seems to be difficult problem (or impossible??). I want to get and read HTTP Response, caused by HTTP Request in browser, under watching Chrome Extension background script. We can get HTTP Request Body in this way

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

I also checked these stackoverflows

Is there any clever way to get HTTP Response Body in Chrome Extension?

I can't find better way then this anwser.

Chrome extension to read HTTP response

The answer told how to get response headers and display in another page.But there is no body info in the response obj(see event-responseReceived ). If you want to get response body without another page, try this.

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);
        });
    }

}

I think it's useful enough for me and you can use chrome.debugger.detach(debuggeeId) to close the ugly tip.

sorry, mabye not helpful... ^ ^

This is definitely something that is not provided out of the box by the Chrome Extension ecosystem. But, I could find a couple of ways to get around this but both come with their own set of drawbacks.

The first way is:

  1. Use a content script to inject our own custom script.
  2. Use the custom script to extend XHR's native methods to read the response.
  3. Add the response to the web page's DOM inside a hidden (not display: none ) element.
  4. Use the content script to read the hidden response.

The second way is to create a DevTools extension which is the only extension that provides an API to read each request.

I have penned down both the methods in a detailed manner in a blog post here.

Let me know if you face any issues! :)

There is now a way in a Chrome Developer Tools extension, and sample code can be seen here: blog post .

In short, here is an adaptation of his sample code:

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.
      }
}
});
});

I show my completed code if it can be some help. I added the underscore to get the request url, thanks

//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));
    }
}

console.log("ended");

To get a XHR response<\/strong> body you can follow the instructions in this answer<\/a> .

Both get the response body without using chrome.debugger.<\/strong>

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);
            })
    })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM