Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome extension: webRequest.onBeforeSendHeaders behaves strange

I am trying to add a "Referer"-HTTP-Header to certain AJAX requests in my Chrome extension. You can't change it directly in the AJAX request so I tried to change it using the webRequest api:

chrome.webRequest.onBeforeSendHeaders.addListener(function(data) {
    console.log("onBeforeSendHeaders fired");
    var xdata=data.requestHeaders;
    xdata.push({
        "name":"Referer",
        "value": "http://the.new/referrer"
    })
    return {requestHeaders: xdata};
}, { //Filter
    urls: ["<all_urls>"], //For testing purposes
    types: ["xmlhttprequest"]
},["requestHeaders","blocking"]);

But this doesn't work for the AJAX requests in my extension. It only fires the event on other AJAX requests but not the ones done in my extension.
Another strange thing is that everything works fine when "blocking" flag is not set, but then I can't change the headers.

Does anyone know a way to solve this (or another way to achieve my goal: changing the "Referer" for a site request and retrieving the contents)

Thank you :)

like image 227
user1449556 Avatar asked Jun 11 '12 19:06

user1449556


3 Answers

Here's a working version that works in all instances (when referer header is already set or when it hasn't been set.)

var requestFilter = {
    urls: ["<all_urls>"]
},

extraInfoSpec = ['requestHeaders', 'blocking'],
handler = function(details) {

var isRefererSet = false;
var headers = details.requestHeaders,
    blockingResponse = {};

for (var i = 0, l = headers.length; i < l; ++i) {
    if (headers[i].name == 'Referer') {
        headers[i].value = "http://your-url.com/";
        isRefererSet = true;
        break;
    }
}

if (!isRefererSet) {
    headers.push({
        name: "Referer",
        value: "http://your-url.com/"
    });
}

blockingResponse.requestHeaders = headers;
return blockingResponse;
};

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

Don't forget to add all the following permissions to your manifest:

"permissions": [  "webRequest", "webRequestBlocking", "<all_urls>" ]
like image 155
ErwanLent Avatar answered Nov 18 '22 10:11

ErwanLent


The reason you can't set the Referrer header when you don't have a blocking request is that the request has potentially already gone out - you are being notified asynchronously, and cannot change anything about the request.

To change headers, I use this code:

function mod_headers(header_array,p_name,p_value) {
     var did_set = false;                                                                                      
     for(var i in header_array) {                                                                                                   
         var header = header_array[i];                                                                                              
         var name = header.name;                                                                                                    
         var value = header.value;                                                                                                  

         // If the header is already present, change it:
         if(name == p_name) {
             header.value = p_value;
             did_set = true;
         }                                                                                                         
     }
     // if it is not, add it:
     if(!did_set) { header_array.push( { name : p_name , value : p_value } ); }                                                                                                                       
 }
like image 30
Daniel Avatar answered Nov 18 '22 10:11

Daniel


With Chrome supporting ES6, modifying a request header can be done like this:

chrome.webRequest.onBeforeSendHeaders.addListener(
  details => {
    details.requestHeaders = details.requestHeaders.filter(rh => rh.name !== 'Referer');
    details.requestHeaders.push({name: 'Referer', value: 'http://the.new/referrer'});
    return {requestHeaders: details.requestHeaders};
  },
  {urls: ['<all_urls>']},
  ['blocking', 'requestHeaders'],
);
like image 43
Blaise Avatar answered Nov 18 '22 12:11

Blaise