Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix($http): remove 'X-Requested-With' from header defaults
Browse files Browse the repository at this point in the history
X-Requested-With header is rarely used in practice and by using
it all the time we are triggering preflight checks for crossdomain
requests.

We could try detecting if we are doing CORS requests or not, but
it doesn't look like it's worth the trouble.

BREAKING CHANGE: X-Requested-With header is not set by $http service
any more. If anyone actually uses this header it's quite easy to add
it back via:

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

Closes #1004
  • Loading branch information
rkirov authored and IgorMinar committed Nov 26, 2012
1 parent a32bc40 commit 3a75b11
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 10 deletions.
4 changes: 1 addition & 3 deletions src/ng/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ function $HttpProvider() {
// default headers
headers: {
common: {
'Accept': 'application/json, text/plain, */*',
'X-Requested-With': 'XMLHttpRequest'
'Accept': 'application/json, text/plain, */*'
},
post: {'Content-Type': 'application/json;charset=utf-8'},
put: {'Content-Type': 'application/json;charset=utf-8'}
Expand Down Expand Up @@ -212,7 +211,6 @@ function $HttpProvider() {
*
* - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
* - `Accept: application/json, text/plain, * / *`
* - `X-Requested-With: XMLHttpRequest`
* - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests)
* - `Content-Type: application/json`
* - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
Expand Down
9 changes: 2 additions & 7 deletions test/ng/httpSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,7 @@ describe('$http', function() {

it('should set default headers for GET request', function() {
$httpBackend.expect('GET', '/url', undefined, function(headers) {
return headers['Accept'] == 'application/json, text/plain, */*' &&
headers['X-Requested-With'] == 'XMLHttpRequest';
return headers['Accept'] == 'application/json, text/plain, */*';
}).respond('');

$http({url: '/url', method: 'GET', headers: {}});
Expand All @@ -389,7 +388,6 @@ describe('$http', function() {
it('should set default headers for POST request', function() {
$httpBackend.expect('POST', '/url', 'messageBody', function(headers) {
return headers['Accept'] == 'application/json, text/plain, */*' &&
headers['X-Requested-With'] == 'XMLHttpRequest' &&
headers['Content-Type'] == 'application/json;charset=utf-8';
}).respond('');

Expand All @@ -401,7 +399,6 @@ describe('$http', function() {
it('should set default headers for PUT request', function() {
$httpBackend.expect('PUT', '/url', 'messageBody', function(headers) {
return headers['Accept'] == 'application/json, text/plain, */*' &&
headers['X-Requested-With'] == 'XMLHttpRequest' &&
headers['Content-Type'] == 'application/json;charset=utf-8';
}).respond('');

Expand All @@ -412,8 +409,7 @@ describe('$http', function() {

it('should set default headers for custom HTTP method', function() {
$httpBackend.expect('FOO', '/url', undefined, function(headers) {
return headers['Accept'] == 'application/json, text/plain, */*' &&
headers['X-Requested-With'] == 'XMLHttpRequest';
return headers['Accept'] == 'application/json, text/plain, */*';
}).respond('');

$http({url: '/url', method: 'FOO', headers: {}});
Expand All @@ -424,7 +420,6 @@ describe('$http', function() {
it('should override default headers with custom', function() {
$httpBackend.expect('POST', '/url', 'messageBody', function(headers) {
return headers['Accept'] == 'Rewritten' &&
headers['X-Requested-With'] == 'XMLHttpRequest' &&
headers['Content-Type'] == 'Rewritten';
}).respond('');

Expand Down

10 comments on commit 3a75b11

@digitlimit
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Laravel / Symphony actually depend on this feature to dictate AJAX requests.

 /**
 * Returns true if the request is a XMLHttpRequest.
 *
 * It works if your JavaScript library sets an X-Requested-With HTTP header.
 * It is known to work with common JavaScript frameworks:
 *
 * @link http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
 *
 * @return bool true if the request is an XMLHttpRequest, false otherwise
 *
 * @api
 */
public function isXmlHttpRequest()
{
    return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
}

@mtpultz
Copy link

@mtpultz mtpultz commented on 3a75b11 Mar 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, and still do 3 years later apparently. This took a bit to track down.

@ceorcham
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same in django...

@timallen527
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .NET MVC IsAjaxRequest still depends on this header as well.

@salesfelipe
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guys, changing the client side is not the answer. Instead you should change how your server handles the CORS request. If you are using Nodejs on your server, you can try this:

// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "
");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});

For more info, check this out:

https://github.com/ccoenraets/directory-ionic-nodejs/blob/master/server.js

@gkalpak
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case anyone missed it, you can add it to all $http requests using $httpProvider#defaults.

@mkonecny
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felippeSales changing the server side is definitely not the answer.

@salesfelipe
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkonecny Actually, it was. I'm building an app using MEAN stack on heroku and Ionic on client side. Thats how I finally fixed it: https://github.com/expressjs/cors/blob/master/README.md

@jonwolski
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old issue, but for posterity's sake:

The presence of this custom header had protected against CSRF. This detrimental change event got a mention on OWASP: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Protecting_REST_Services:_Use_of_Custom_Request_Headers

@gkalpak
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonwolski, also note that $http uses a different header, X-XSRF-HEADER (the name of the header is configurable), specifically for protecting against CSRF vulnerabilities.

Please sign in to comment.