Why the difference in using common and post for changing the ContentType should affect the request payload / form data?

StackOverflow https://stackoverflow.com/questions/21215420

Question

If I use the following:

a)

angularApp.config(function ($httpProvider) {
  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
  $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
  $httpProvider.defaults.headers.common['Accept'] = 'application/json';
  $httpProvider.defaults.transformRequest = function(data) {
      if (data === undefined) {
          return data;
      }
      return $.param(data);
  }
});

versus

b)

angularApp.config(function ($httpProvider) {
  $httpProvider.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
  $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
  $httpProvider.defaults.headers.common['Accept'] = 'application/json';
  $httpProvider.defaults.transformRequest = function(data) {
      if (data === undefined) {
          return data;
      }
      return $.param(data);
  }
});

And then when I use a $http.post or a $resource that uses POST

a) is what I want because I get this in the Chrome Dev Tools:

  Form Data:
    User[old_password]:xxx
    User[new_password]:yyyy
    User[new_password_confirm]:yyyy

b) is NOT what I want because I get this in the Chrome Dev Tools:

Request Payload:
User%5Bold_password%5D=xxx&User%5Bnew_password%5D=yyyy&User%5Bnew_password_confirm%5D=yyyy

This puzzles me because I expect common to apply for everything including post.

The only difference between a) and b) is b) has

  $httpProvider.defaults.headers.**common**['Content-Type'] = 'application/x-www-form-urlencoded';

I am using angular 1.2.6.

Issue also occurs in 1.2.9

Please advise.

Was it helpful?

Solution

Inside your config block type this:

console.log($httpProvider.defaults.headers.post); 

// Object {Content-Type: "application/json;charset=utf-8"} 

As you can see, $http already has a default header for a post method.

When you declare common headers $http would not override the method specific headers with the common headers. The opposite is the true, first the common headers are applied then the method specific headers override them (if exist).

You can reset the defaults like so:

$httpProvider.defaults.headers.post = {};

Inside http.js you can see how headers are being merged:

function mergeHeaders(config) {
  var defHeaders = defaults.headers,
      reqHeaders = extend({}, config.headers),
      defHeaderName, lowercaseDefHeaderName, reqHeaderName;

  defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);

When using Angular.extend, the properties of later object overrides the properties of any preceding objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top