Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome extension to read HTTP response

I have this Chrome extension that modifies the header of requests before sending them. I now would like to be able, within the same extension, to check the header of the response. I searched throughout the Chrome Extension APIs but I couldn't find anything of interest.

This is the code I use for modifying the header of the request, maybe it's useful for you to know how I do it.

chrome.webRequest.onBeforeSendHeaders.addListener(
      function(details) {/*do something*/},
      {urls: ["<all_urls>"]},
      ["blocking", "requestHeaders"]);

Does anyone knows how to do that, or can point me to an interesting source? Thanks

like image 380
Masiar Avatar asked Jan 20 '12 09:01

Masiar


People also ask

How do I view responses to a website in Chrome?

To view the request or response HTTP headers in Google Chrome, take the following steps : In Chrome, visit a URL, right click , select Inspect to open the developer tools. Select Network tab. Reload the page, select any HTTP request on the left panel, and the HTTP headers will be displayed on the right panel.

What is the API used for webRequestBlocking?

To use the webRequest API for a given host, an extension must have the "webRequest" API permission and the host permission for that host. To use the "blocking" feature, the extension must also have the "webRequestBlocking" API permission.


1 Answers

I achieved capturing all HTTP requests and responses made by a website, by injecting a script to DOM. I injected injected.js to DOM using following script:

/**
 * code in inject.js
 * added "web_accessible_resources": ["injected.js"] to manifest.json
 */
var s = document.createElement('script');
s.src = chrome.extension.getURL('injected.js');
s.onload = function() {
    this.remove();
};
(document.head || document.documentElement).appendChild(s);

This would inject injected.js in website(s) that match "content_scripts" "matches" in manifest.json. Mention contentscript.js and inject.js in "js". Also, make sure you have mentioned the website in the "permissions" in manifest.json. See manifest.json at the end of answer.

Now, the code in injected.js which does the actual capturing of requests and responses is inspired from How we captured AJAX requests from a website tab with a Chrome Extension. Also see the comment section in that article.

The injected.js is as follows:

(function(xhr) {

    var XHR = XMLHttpRequest.prototype;

    var open = XHR.open;
    var send = XHR.send;
    var setRequestHeader = XHR.setRequestHeader;

    XHR.open = function(method, url) {
        this._method = method;
        this._url = url;
        this._requestHeaders = {};
        this._startTime = (new Date()).toISOString();

        return open.apply(this, arguments);
    };

    XHR.setRequestHeader = function(header, value) {
        this._requestHeaders[header] = value;
        return setRequestHeader.apply(this, arguments);
    };

    XHR.send = function(postData) {

        this.addEventListener('load', function() {
            var endTime = (new Date()).toISOString();

            var myUrl = this._url ? this._url.toLowerCase() : this._url;
            if(myUrl) {

                if (postData) {
                    if (typeof postData === 'string') {
                        try {
                            // here you get the REQUEST HEADERS, in JSON format, so you can also use JSON.parse
                            this._requestHeaders = postData;    
                        } catch(err) {
                            console.log('Request Header JSON decode failed, transfer_encoding field could be base64');
                            console.log(err);
                        }
                    } else if (typeof postData === 'object' || typeof postData === 'array' || typeof postData === 'number' || typeof postData === 'boolean') {
                            // do something if you need
                    }
                }

                // here you get the RESPONSE HEADERS
                var responseHeaders = this.getAllResponseHeaders();

                if ( this.responseType != 'blob' && this.responseText) {
                    // responseText is string or null
                    try {

                        // here you get RESPONSE TEXT (BODY), in JSON format, so you can use JSON.parse
                        var arr = this.responseText;

                        // printing url, request headers, response headers, response body, to console

                        console.log(this._url);
                        console.log(JSON.parse(this._requestHeaders));
                        console.log(responseHeaders);
                        console.log(JSON.parse(arr));                        

                    } catch(err) {
                        console.log("Error in responseType try catch");
                        console.log(err);
                    }
                }

            }
        });

        return send.apply(this, arguments);
    };

})(XMLHttpRequest);

For reference, my manifest.json is:

{
  "manifest_version": 2,

  "name": "Extension Name",
  "description": "Some Desc.",
  "version": "1.1",

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "activeTab",
    "storage",
    "tabs",
    "*://website.com/*"
  ],
  "content_scripts": [
    {
      "matches": ["*://website.com/*"],
      "run_at": "document_start",
      "js": ["contentscript.js", "inject.js"]
    }
  ],
  "web_accessible_resources": ["injected.js"]
}

Hope this helps.

like image 152
user5155835 Avatar answered Nov 16 '22 17:11

user5155835