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

$resource should support custom http headers #736

Closed
vojtajina opened this issue Jan 26, 2012 · 25 comments
Closed

$resource should support custom http headers #736

vojtajina opened this issue Jan 26, 2012 · 25 comments

Comments

@vojtajina
Copy link
Contributor

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

@pmoelgaard
Copy link

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

@pmoelgaard
Copy link

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 ?

@robshep
Copy link

robshep commented Jun 2, 2012

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

maxmart added a commit to maxmart/angular.js that referenced this issue Jun 5, 2012
@ibotty
Copy link

ibotty commented Aug 7, 2012

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

@sbronstein
Copy link

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

@mhevery mhevery closed this as completed in 9b5656e Sep 4, 2012
mhevery pushed a commit that referenced this issue Sep 5, 2012
mhevery pushed a commit to mhevery/angular.js that referenced this issue Sep 7, 2012
@pascalwhoop
Copy link

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:
https://github.com/Ineffective/Steak-Mobile
and the method which tries to use the custom header functionality is in line 31 here:
https://github.com/Ineffective/Steak-Mobile/blob/master/src/main/webapp/app/services.js

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

@lrlopez
Copy link
Contributor

lrlopez commented Nov 11, 2012

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 http://docs.angularjs.org/misc/contribute

@pascalwhoop
Copy link

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?

@pkozlowski-opensource
Copy link
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: http://ci.angularjs.org/view/AngularJS/job/angular.js-angular-master/ws/build/

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.

@pascalwhoop
Copy link

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

@pascalwhoop
Copy link

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) {
    $browser.$$incOutstandingRequestCount();
    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();
      xhr.open(method, 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:

http://img404.imageshack.us/img404/9101/screengithub.png

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' ?

@pascalwhoop
Copy link

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

@hiteshjoshi
Copy link

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

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

                            }
                        }
          })

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

@unbalanced
Copy link

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

@calvinfroedge
Copy link

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

@calvinfroedge
Copy link

Got it! Set in $httpProvider defaults.

@RomaLefrancois
Copy link

Got it! Set in $httpProvider defaults.

Like this :

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

@micmmakarov
Copy link

What if I have different headers for different resources?

@iQuarK
Copy link

iQuarK commented Sep 5, 2013

You can define the header for each resource:

$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()}
        }
      }
)

@augkamil
Copy link

augkamil commented Dec 5, 2013

Hi all,
I tried to make a request like:

angular.module("app").factory "Query", ($resource) ->
  $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)

@jreading
Copy link

^ same. What up with that?

@jreading
Copy link

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);

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

@eddiemonge
Copy link
Contributor

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

@jamshid
Copy link
Contributor

jamshid commented Nov 26, 2014

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 https://docs.angularjs.org/api/ngResource/service/$resource that Conten-type is not overridable. And https://docs.angularjs.org/api/ng/service/$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.

@ifbbprochris
Copy link

why I set like this '$httpProvider.defaults.headers.post = {}' here come to differents,
one like this:
return $resource
(server, {},
{
login:{
method: 'post'
}
}
);
this is success,
another one like this:
return $resource
(server, {},
{
deviceList:{
method:"post",
headers:{
'Authorization': 'JWT ' + access_token
}
}
}
);
this is fail and say 'Response for preflight is invalid (redirect)'

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests