Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

chrome.webRequest not working?

I'm trying to implement the chrome.webRequest API in my extension but for some reason it's just not working no matter what I do. Can someone post an example of usage? or correct my mistakes? Basically what I'm trying to do is to intercept the recieved headers from a response.

This is an implementation for onBeforeSendHeaders but I'd like to use OnHeadersRecieved as well :

var requestFilter = {
    urls: [ "<all_urls>" ]
  },
  // The 'extraInfoSpec' parameter modifies how Chrome calls your
  // listener function. 'requestHeaders' ensures that the 'details'
  // object has a key called 'requestHeaders' containing the headers,
  // and 'blocking' ensures that the object your function returns is
  // used to overwrite the headers
  extraInfoSpec = ['requestHeaders','blocking'],
  // Chrome will call your listener function in response to every
  // HTTP request
  handler = function( details ) {
    alert(details);
    var headers = details.requestHeaders,
      blockingResponse = {};

    // Each header parameter is stored in an array. Since Chrome
    // makes no guarantee about the contents/order of this array,
    // you'll have to iterate through it to find for the
    // 'User-Agent' element
    for( var i = 0, l = headers.length; i < l; ++i ) {
      if( headers[i].name == 'User-Agent' ) {
        headers[i].value = '>>> Your new user agent string here <<<';
        break;
      }
      // If you want to modify other headers, this is the place to
      // do it. Either remove the 'break;' statement and add in more
      // conditionals or use a 'switch' statement on 'headers[i].name'
    }

    blockingResponse.requestHeaders = headers;
    return blockingResponse;
  };

chrome.webRequest.onBeforeSendHeaders.addListener( handler, requestFilter, extraInfoSpec );

this is my manifest file:

    {
   "background_page": "iRBackground.html",
   "browser_action": {
      "default_icon": "Off.png",
      "popup": "iRMenu.html"
   },
   "content_scripts": [ {
      "js": [ "Content.js" ],
      "matches": [ "http://*/*" ],
      "run_at": "document_start"
   } ],
   "description": "***",
   "icons": {
      "128": "On128x128.png",
      "16": "On.png",
      "48": "On48x48.png"
   },
   "key": "****",
   "manifest_version": 2,
   "name": "***",
   "permissions": [ "tabs", "notifications", "unlimitedStorage", "webRequest", “webRequestBlocking”, “<all_urls>”],
   "update_url": "***/Chrome/UpdateVersion.xml",
   "version": "1.3"
}

the error I get from Chrome is: Uncaught TypeError: Cannot read property 'onBeforeSendHeaders' of undefined

Anyone see anything wrong??? thanks

like image 380
user1326293 Avatar asked Mar 19 '13 14:03

user1326293


People also ask

How do I send a post request extension in Chrome?

Type the url in the main input field and choose the method to use: GET/POST/PUT/DELETE/PATCH. Click on the arrow "Send" or press Ctrl+Enter. You'll see info about the response (time, size, type) and you'll be able to see the content response in the response section.

What is Webrequest API?

# Life cycle of requests. The web request API defines a set of events that follow the life cycle of a web request. You can use these events to observe and analyze traffic. Certain synchronous events will allow you to intercept, block, or modify a request.


2 Answers

Well for an example of usage I can give you this working code. I wrote it this way because the other way seems backwards to me but that is just my personal preference, they should both work the same.

Manifest

{   "name": "Chrome webrequest test",   "version": "0.1",   "description": "A test for webrequest",   "manifest_version": 2,   "permissions": [     "<all_urls>","webRequest","webRequestBlocking"   ],   "background": {     "scripts": ["bgp.js"],     "persistent": true   } } 

bgp.js

chrome.webRequest.onBeforeSendHeaders.addListener(function(details){   //console.log(JSON.stringify(details));   var headers = details.requestHeaders,   blockingResponse = {};    // Each header parameter is stored in an array. Since Chrome   // makes no guarantee about the contents/order of this array,   // you'll have to iterate through it to find for the   // 'User-Agent' element   for( var i = 0, l = headers.length; i < l; ++i ) {     if( headers[i].name == 'User-Agent' ) {       headers[i].value = '>>> Your new user agent string here <<<';       console.log(headers[i].value);       break;     }     // If you want to modify other headers, this is the place to     // do it. Either remove the 'break;' statement and add in more     // conditionals or use a 'switch' statement on 'headers[i].name'   }    blockingResponse.requestHeaders = headers;   return blockingResponse; }, {urls: [ "<all_urls>" ]},['requestHeaders','blocking']); 
like image 56
BeardFist Avatar answered Sep 22 '22 14:09

BeardFist


I just fixed this in my extension here: https://github.com/devinrhode2/tweet-bar What I needed to do was use chrome.webRequest.onBeforeSendHeaders.addListener, but that also meant adding in the webRequest, webRequestBlocking permissions.. would be better to use declarativeWebRequest, but this project isn't that important to me.

Key things:

  • manifest.json "background": { "persistent": true,
  • "permissions": [ "webRequest", "webRequestBlocking",

When you make these changes in the manifest.json, you should actually consider re-installing the extension just to make sure the change is being picked up.

This is my filter code. Yours should not be identical. See the docs here https://developer.chrome.com/extensions/webRequest

chrome.webRequest.onBeforeSendHeaders.addListener((req) => {
  console.log('onBeforeSendHeaders');
  req.requestHeaders.forEach(function(header, index){
    console.log(header.name+':', header.value);
    if (headers[header.name.toLowerCase()]) {
      console.log('set header:'+header.name, 'to:'+headers[header.name.toLowerCase()]);
      req.requestHeaders[index].value = headers[header.name.toLowerCase()]
    }
  })
  return {requestHeaders: req.requestHeaders};
},{
  urls: ['https://twitter.com/i/tweet/create'],
  types: ["xmlhttprequest"]
},[
  'blocking',
  'requestHeaders'
]);

I also added these headers to my xhr request, which doesn't hurt, makes you appear more similar to the normal site:

  //add headers:
  var headers = {
    'content-type': 'application/x-www-form-urlencoded',
    accept: 'application/json, text/javascript, */*; q=0.01',
    origin: 'https://twitter.com',
    referer: 'https://twitter.com/',
    'x-requested-with': 'XMLHttpRequest'
  };
  console.log('change')
  Object.keys(headers).forEach((header) => {
    postXhr.setRequestHeader(header, headers[header]);
  })
like image 37
Devin Rhode Avatar answered Sep 23 '22 14:09

Devin Rhode