javascriptgoogle-chrome-extensionchrome-extension-manifest-v3chrome-declarativenetrequest

How to get Requested API Response Body in chrome extension manifest version 3


I am working on manifest version 3 and stuck in an endless loophole for getting the response body by requested API in the chrome extension.

Goal is to have all requested API response

here's the code.

manifest.json

{
  "name": "Chapter 28 (MV3)",
  "version": "1.0",
  "manifest_version": 3,
  "description": "This is Chapter 28",
  "declarative_net_request" : {
    "rule_resources" : [{
      "id": "ruleset_1",
      "enabled": true,
      "path": "rules_1.json"
    }]
  },
  "permissions": [
    "declarativeNetRequest",
    "declarativeNetRequestFeedback"
  ],
  "background": {
    "service_worker": "background.js"
  }
}

rules_1.json

  [
  {
    "id": 1,
    "priority": 1,
    "action": {
      "type": "block"
    },
    "condition": {
      "urlFilter": "yahoo.co.jp",
      "resourceTypes": ["main_frame"]
    }
  },
  {
    "id": 2,
    "priority": 1,
    "action": {
      "type": "allow"
    },
    "condition": {
      "resourceTypes": ["main_frame", "xmlhttprequest"]
    }
  }
]

background.js

chrome.declarativeNetRequest.onRuleMatchedDebug.addListener((mrd) => {
  console.log(mrd)
});

Solution

  • So here's the thing that , it cant be done API so I used a inject method to get it fixed , below is fixed code so it can help others too

    Manifest.json

    {
      "name": "officialbrajesh",
      "version": "1.0",
      "manifest_version": 3,
      "description": "This is Test Extension",
      "web_accessible_resources": [{
      "resources": ["inject.js"],
      "matches": ["<all_urls>"]
    }],
    "content_scripts": [
       {
         "matches": ["<all_urls>"],
         "js": ["contentscript.js"]
       }
     ],
      "permissions": [
      "tabs"
      ],
      "background": {
        "service_worker": "background.js"
      }
    }
    

    contentscrript.js

    var s = document.createElement('script');
    s.src = chrome.runtime.getURL('inject.js');
    s.onload = function() {
        this.remove();
    };
    (document.head || document.documentElement).appendChild(s);
    
    
    document.addEventListener('yourCustomEvent', function (e) {
      var data = e.detail;
      console.log('content script');
      console.log('received', e);
    });
    

    inject.js

    (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 (myUrl.indexOf('https://i.instagram.com/api/v1') !== -1) {
                        console.log(myUrl);
                        var responseData = this.response;
                        console.log(responseData);
                        document.dispatchEvent(new CustomEvent('yourCustomEvent', { url : myUrl, detail: responseData }));                  
                    }
                }
            });
            return send.apply(this, arguments);
        };
    
    })(XMLHttpRequest);