25

Angular.js, when accessing a web service using the $http object, automatically adds a X-Requested-With:XMLHttpRequest header to the request.

The web service I am accessing using CORS doesn't support X-Requested-With header, so I tried to eliminate it but I can't acess the $httpProvider object. I get an undefined object error, and if I reference it in the controllers parameters, so that angular injects it I get a "Error: Unknown provider: $httpProviderProvider <- $httpProvider"

So I wonder how can I access the $httpProvider, like it says in the docs (http://docs.angularjs.org/api/ng.$http) to tell angular.js not to send that header...

opensas
  • 60,462
  • 79
  • 252
  • 386

4 Answers4

26
angular.module('myModule', [])
    .config(['$httpProvider', function($httpProvider) {
        delete $httpProvider.defaults.headers.common["X-Requested-With"]
    }])
Justen
  • 4,859
  • 9
  • 44
  • 68
  • When I do this, it works fine in Chrome, but seems to have the side-effect of sending the request header 'Origin' as 'null'. This is very bad because my server returns the response header 'Access-Control-Allow-Origin' with the same value it receives from the request 'Origin', therefore the CORS fails in the browser. – David Frahm Jul 17 '13 at 20:41
  • In my comment above, I forgot to specify that the browser where it fails (sending the request header 'Origin' as 'null') is Safari, both Mac and iOS. – David Frahm Jul 17 '13 at 21:01
  • How to add it back, but not in config, in `$http` promise itself? seems `$httpProvider.defaults.headers.common["X-Requested-With"]` is an Array? – Medet Tleukabiluly Aug 19 '14 at 08:27
11

I found that, besides Justen answer, I can also do it on a per request basis like this:

delete $http.defaults.headers.common['X-Requested-With']
opensas
  • 60,462
  • 79
  • 252
  • 386
  • 7
    what's the difference between `$http.defaults.headers.common…` and `$httpProvider.defaults.headers.common…` ? – François Romain Sep 20 '13 at 13:11
  • 3
    no difference. using $httpProvider you configure headers before $http service is constructed; but using $http you add headers right after $http service is creates. In common there is no difference – pleerock Feb 18 '14 at 13:18
6

Since Angular JS version 1.1.1 removing the header is no longer necessary.

See the change log:
https://github.com/angular/angular.js/blob/master/CHANGELOG.md#111-pathological-kerning-2012-11-26

For people like me who were using the header to identify ajax requests and respond to them differently.

e.g. making a request after the session expires.

You can re-enable the header like so:

angular.module('yourModule', [])
.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);
Community
  • 1
  • 1
Josue Alexander Ibarra
  • 8,269
  • 3
  • 30
  • 37
  • Nice to read all the way down here and notice this ;) No need to manually remove the CORS preflight checks: `prevent CORS preflight checks by removing X-Requested-With from header defaults` – atconway Aug 26 '14 at 02:31
  • Instead of `X-Requested-With`, you should use standard HTTP headers like `Accept` to disambiguate XHR calls from regular HTTP calls. Standard headers do not trigger a preflight check for CORS and therefore reduce latency by 50%. – bluesmoon Aug 14 '15 at 12:53
0

Since Angular JS version 1.1.1 removing the header is no longer necessary. This change got mentioned on https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Protecting_REST_Services:_Use_of_Custom_Request_Headers

As shown by Josue, this can be easily added to all requests again as follows:

angular.module('yourModule', [])
    .config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
    }]);

Set the configuration for the header to undefined to remove the header for specific external requests.

let urlExternalValidator = 'https://openiban.com/validate/' + this.iban + '?getBIC=true&validateBankCode=true';
this.$http.get(urlExternalValidator, {
    // simple request to not trigger a CORS preflight
    // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    headers: {
        'X-Requested-With': undefined
    }
})

In addition, you can supply a headers property in the config object passed when calling $http(config), which overrides the defaults without changing them globally.

To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis, Use the headers property, setting the desired header to undefined

https://docs.angularjs.org/api/ng/service/$http#setting-http-headers

ofthelit
  • 1,341
  • 14
  • 33