Why the difference in using common and post for ch

2019-07-22 02:15发布

问题:

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.

回答1:

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.