Is it possible to force chrome not to send the cookie header on an XMLHttpRequest. I see that Firefox has an anon parameter, but is there something similar on chrome/webkit?
1 Answers
Unfortunately, there is no straightforward way in webextensions at the moment (both in Firefox and Chrome). Let us look at the alternatives:
- Use
fetch
instead of XMLHttpRequest - Modify request headers using the webRequest API
Option 1 has the charm that it does not involve hacks, but the downside is that fetch
is currently still missing some functionality that exists in XMLHttpRequest
. Whether that is a problem, depends on your concrete example.
Option 2 requires permission to use the webRequest API, which requires additional permissions. Also it looks more complicated than it should be. Still, it is the only way that I got working and which can be used on today's browsers (Nov 2017).
But let us look at both options in detail.
Option 1: fetch API and its limitations
When you mention anonymous requests in Firefox, I'm sure you mean code like this:
let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Components.interfaces.nsIXMLHttpRequest);
xhr.open('GET', 'http://www.example.com');
xhr.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_ANONYMOUS;
xhr.send();
With XMLHttpRequest
in Chrome it is not possible, but the closest thing that you can get today is to avoid sending cookies by using the fetch API, which has a similar option called credentials
, which lets you control whether cookies should be included ('include'
) or not ('omit'
):
fetch('http://www.example.com', { credentials: 'omit' }).then(...);
This will make a GET request without setting any cookies.
There are still some limitations in terms of functionality in comparison to XMLHttpRequest
. The most pressing issue from my perspective is that you cannot abort requests started with fetch
, nor do you have control over timeouts.
There is a new standard to support abortable fetch
(see AbortController API), but it is currently only implemented on Firefox 57 and Edge (in Nov 2017). It will soon arrive in Chrome, but if you need the functionality now, it might not be an option to wait until all browsers support it.
Still, once AbortController
is there, I assume it will become the preferred way to avoid sending cookies.
Option 2: webRequest API and removing the 'Cookie' header manually
If you need a working solution now, and you have permission in the extension to access the webRequest API, you can install a onBeforeSendHeaders
listener and manually remove the Cookie
header.
To get an idea, this is how it could look like:
chrome.webRequest.onBeforeSendHeaders.addListener((details) => {
return {
requestHeaders: details.requestHeaders.filter(x => x.name.toLowerCase() !== 'cookie');
};
}, { urls: ['<all_urls>'] }, ['requestHeaders', 'blocking']);
But you have to be careful that you do not accidentally modify unrelated requests. In a real implementation, you should verify whether the details.requestId
matches. To get access to the request id, I used another onBeforeRequestListener and verified whether the URL of the request seems to match. When the request is done, all listeners are removed again. (For more details, see How to get the requestId of a new request?.)
From what I see, it works but it is not a very elegant solution.
Summary:
fetch API:
- (+) Straightforward solution via
crendentials: 'omit'
- (+) New standard which is intended to replace
XMLHttpRequest
- (-) Current browsers do not yet support all features (timeouts, cancellation)
webRequest API:
- (+) works on today's browsers (tested on Chrome)
- (-) very complex solution for a simple problem
- (-) requires extra permissions to use it

- 41,306
- 31
- 146
- 239