Skip to content


$resource should support custom http headers #736

vojtajina opened this Issue · 24 comments

when creating a resource definition it should be possible to define what headers should be sent along with the request when the action is invoked


What is the status on this one ?
It seems not be possible as of now, and I don't seem to be able to find it in the Trello Product Back Log...

I'm stuck right now, hoping to use the Resource abstraction, however I need to set the Authorization header and it seems to be extremely cumbersome to achieve this by using the Resource abstraction


it would be nice to be able to apply(override) all the params for the $http call in the $resource abstraction.... and not only pass in overrides to the parameters for the URL

Feature request ?

@maxmart maxmart added a commit to maxmart/angular.js that referenced this issue
@maxmart maxmart Fix for issue #736: ngResource now accepts headers c159b3d

Great stuff, we also need to pop in an "Authorization" header, Hopefully this will do the trick.

@maxmart maxmart added a commit to maxmart/angular.js that referenced this issue
@maxmart maxmart feat($resource): allow defining headers per action
Closes #736

is there any activity here? this would be really nice to have.


+1! maybe @vojtajina wants @maxmart to merge his two commits into one commit with the desired commit format?

@mhevery mhevery added a commit that closed this issue
@maxmart maxmart feat(resource): accept headers
Closes #736
@mhevery mhevery closed this in 9b5656e
@mhevery mhevery added a commit that referenced this issue
@maxmart maxmart feat(resource): accept headers
Closes #736
@mhevery mhevery added a commit to mhevery/angular.js that referenced this issue
@maxmart maxmart feat($resource): support custom headers per action
Closes #736

I tried using this feature (custom headers) in my current project but cannot seem to get it to work. I have it on Github here:
and the method which tries to use the custom header functionality is in line 31 here:

I tried adding a header for authorization as well as trying to tell the server that i want json as a response (default is xml)

I used v.1.0.1, 1.0.2 and 1.1.0, none seem to support it? Any hints on why it's not working would be greatly appreciated


I don't know for sure, but it seems that the feature landed two months ago into the 1.0.x branch (b936e52), but 8 hours ago that feature was removed as it adds a new feature into a stable branch (look here: 29541e7).

I suppose that custom headers will be still available on master. Did you try to download and build the current master?
You can follow the instructions from the "Checking Out and Building Angular" section in


I guess I could also just use the lower level $http since there it should be possible to add a custom header right? I'll follow those instructions you provided but I don't understand why the feature was taken out again a few hours ago?
Could you elaborate why they would take such an important feature out again?

Angular member

@Ineffective it was just remove from the bug-fix branch (1.0.x), it is still in master and will be released in version of 1.1.x.

It was taken out from the bug-fix branch since it was committed in there by accident, this branch should only have bug fixes and no new features.

The actual fix is still in master, if you want to test it you can grab the latest build from master:

Be warned thought, it is just a SNAPSHOT build so it is not the same stability as the released version. Should be good for dev thought.


I just created my own build (v.1.1.1) and included those two files (angular.js and resource.js) into my project. Still my custom headers don't show in the dev tools (chrome). I see my GET request, but I get a 401 HTTP Error back and I cannot see my headers.
This really bugs me. I can see the implementaiton of custom headers in the resource.js source code but they won't be added to my request sent


I think I might have found something:

I debugged into the source code and found the following: (found in Angular 1.0.1 angular.js)

function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
  // TODO(vojta): fix the signature
  return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
    url = url || $browser.url();

    if (lowercase(method) == 'jsonp') {
      var callbackId = '_' + (callbacks.counter++).toString(36);
      callbacks[callbackId] = function(data) {
        callbacks[callbackId].data = data;

      jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId),
          function() {
        if (callbacks[callbackId].data) {
          completeRequest(callback, 200, callbacks[callbackId].data);
        } else {
          completeRequest(callback, -2);
        delete callbacks[callbackId];
    } else {
      var xhr = new XHR();, url, true);
      forEach(headers, function(value, key) {
        if (value) xhr.setRequestHeader(key, value);

my method is specified as jsonp, since the code lies locally on my hard drive and the request is being made to a REST Service provided by our companies servers. so it executes the code in the if(..){...} block

Here is a screenshot that shows my debugging status:

Why aren't the headers passed along with the rest in the

completeRequest(callback, 200, callbacks[callbackId].data);

method? This is where my headers get lost i think. However idk why this only applies to me and not to any http request with custom headers. Is it because my request is 'jsonp' ?


Okay so I talked to one of our seniors and he told me about the general principle of cross domain AJAX and its implications when trying to access another server through javaScript. Good for securitys sake, bad for me, since I need to either implement CORS or set up a proxy servlet on my jetty which forwards all requests to my actual backend and then returns its answers. Anyways what I learned is, it wasn't my fault, it's just that JSONP doesn't let me. damn java development experience...didnt teach me this ;)

Maybe you could include somewhere in the documentation a disclaimer saying "NOTE: NO CUSTOM HEADERS POSSIBLE WITH JSONP" or something. So that others won't go crazy about the same stuff i just did


Hello.. How do I override the headers? I am doing this,

               return $resource(api+'users/login',{},{
                        params : {login:'iamhitesh',password:'hitesh180'},
                            'Content-Type': 'application/x-www-form-urlencoded',
                                            'X-Mcf-Client' : 'web'


but the content-type headers are always application/xml .. why?


Did you try:
$http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
just found it out now.. :)


I just built from 1.1.2-7dff7bb6 and was unable to change default headers to application/json


Got it! Set in $httpProvider defaults.


Got it! Set in $httpProvider defaults.

Like this :

.config(function($httpProvider) {
    $  = {'Content-Type': 'application/x-www-form-urlencoded'};

What if I have different headers for different resources?


You can define the header for each resource:

      $rootScope.routes.route1 + ':uri/:action/',
        resource1: {
          method: 'GET',
          params: {uri: $rootScope.api_services.service1},
          headers: {'Authorization':'Bearer '+User.getAccessToken()}
        resource2: {
          method: 'GET',
          params: {
            uri: $rootScope.api_services.service2,
            action: $rootScope.api_services.action2
          headers: {'Authorization':'Bearer '+User.getAccessToken()}

Hi all,
I tried to make a request like:

angular.module("app").factory "Query", ($resource) ->
    API_URI + "query/:id",
    { id: "@id" },
      getAll: {
        method: "POST",
        isArray: true,
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'

but it doesn't sets the header right. I still get the Content-Type 'application/json'.
I want to set it only for the action getAll() not as default. Maybe someone can help (I'm using angular version 1.2.3)


^ same. What up with that?


Turns out $resource doesn't roll with the only solution. You need to use the $http lower level methods and set the header to undefined so that Angular can set the boundary (transformRequest).

    $scope.uploadFile = function(file){
        var formData = new FormData();
        formData.append('file', file);

            method: 'POST',
            url: 'the/url/to/accept/the/file',
            data: formData,
            headers: { 'Content-Type': undefined },
            transformRequest: function(data) { return data; }

Why is this issue closed? Doesn't seem like it is resolved. cc @mhevery


Same here, can't set Content-type request header in my action. It's ignored and the server always gets 'application/json' .

Stepped into all this and I see angular-resource.js resourceFactory() has my header value, but it gets ignored because Content-type is in default.headers for POST (it's set to application/json).

Is this intentional or a bug? It's not called out in the docs$resource that Conten-type is not overridable. And$http implies setting the headers object on a per-request basis will override the default, but I guess that's at a different level than $resource.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.