Reading response headers when using $http of Angularjs - angularjs

I am using $http to make an api call which is sending some custom header like X-Foo. However I can't yet figure out how to read them. Inside the $http({...}).success(function (data, status, headers, config) {...}) function, headers is a function that should give me a hash of all headers but it only shows the header content-type. Is there a way to get the response headers ?

The custom headers will be visible in same domain. However, for the crossdomain situation, the server has to send Access-Control-Expose-Headers: X-Foo, ... header to make the custom headers visible.

Spring 4.0+ provide #CrossOrigin annotation which has following parameters
origins = list of Comma separated origin.
exposedHeaders = list ofcomma separated count custom parameters.
example
#CrossOrigin(origins = "*", exposedHeaders ="X-Total-Count")

Related

How to get Accept-Language request header value on client

I need to know Accept-Language request header value in order to make a translation on a page. I've tried to create an interceptor like
$httpProvider.interceptors.push(requestInterceptor);
, but in the method
request: function (config) {
of my interceptor I don't see Accept-Language header. I see Accept, Cache-Control, If-Modified-Since, Pragma but in the browser I do see Accept-Language.
Not all request headers are available in AngularJS request interceptor's config parameter. other header values are browser settings that are added while constructing the request.
You could use, but i'm not sure it gives you the right language.
var language = window.navigator.userLanguage or
window.navigator.language;
Only the server can see the value of Accept-Language. So i think the best way is to get this value from the server response-body and memorize it in you cookies (name example AcceptLanguageCookie) and after that you can overide the Accept-Language someway like this in your interceptor.
var app = angular.module("app", []);
app.config(["$httpProvider", function($httpProvider) {
// set Accept-Language header on all requests
$httpProvider.defaults.headers.common["Accept-Language"] = $cookies.get("AcceptLanguageCookie");
}]);

ngResource Dynamically Set Header on Each Request

I see it isn't possible to edit headers with ngRessource after the service has been registered.
Isn't this a big problem for people using authentication via jwt tokens in the autorization header ?
I have to be able too set headers dynamically on each request :
{ Authorization: 'Bearer '+ myAuthService.getToken() }
It poses no problem what so ever with $http.
Is it really impossible to set tokens in the headers via ngRessource after the service has been registered ?
I have to be able too set headers dynamically on each request :
To set the header on each request, make the header a function:
{ Authorization: function(config) {
return 'Bearer '+ myAuthService.getToken();
}
}
From the Docs:
headers – {Object} – Map of strings or functions which return strings representing HTTP headers to send to the server. If the return value of a function is null, the header will not be sent. Functions accept a config object as an argument.
By furnishing a function, the header value will be computed on each request.

Restangular 1.4 setDefaultHeaders failing?

I am having trouble with Restangular 1.4 sending authorization headers to an external web api, which challenges if no such header is provided.
In the following code I try to set the default headers to include basic auth header, but when I look at Fiddler it tells me that no authorization header is present from the start, so the api call is rejected as unauthorized.
Does anyone know if this a bug in Restangular, or whether there is something lacking in the way I have tried to code the auth header?
angular.module('MyAPIService', ['restangular']).factory('MyAPIService', function (Restangular) {
Restangular.setBaseUrl('http://mywebapi/api/');
var encoded = Base64.encode(username + ":" + password);
Restangular.setDefaultHeaders({ Authorization: 'Basic ' + encoded });
return Restangular.one('users', username).get();
Try to set headers in configuration block (not sure about factories). My code looks like this:
angular.module('app', ['restangular'])
.config(['RestangularProvider', function (RestangularProvider) {
// ... some code here
RestangularProvider.setDefaultHeaders({
token: 'some-secret-token'
// other headers
});
// ... some code here
}]);
and works for me.
Turns out that the issue is that the Authorization header is null for all preflight (i.e.) OPTIONS request. (to learn about them, see the section on Preflighted Requests at [https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS). So since I was able to control the API's Basic Auth handling, I made the API not issue a 401 challenge for such preflight requests. The Authorization header was present on non-preflight requests (GET,POST,PUT,DELETE).

In an Angular http response interceptor, how can I get at the actual xhr object?

The method for a response interceptor is:
return {
response: function(response) {
// processing here
}
};
Because of the issues with CORS response headers and various bugs, I want to access the xhr object directly and retrieve specific headers. However, response seems to only have:
data - the returned body
config - the original request
status - the response status
headers() - the problematic function that gets stuck on the bugs
How can I get at the actual xhr object so I can look at the headers directly?
For reference: AngularJS and Apiary.IO - can't read any response headers?
I want to do option 3, and work with xhr directly, but how do I get to it in an interceptor?
I don't think there's a way to access the xhr object directly exposed to interceptors. However, If this is all due to the Firefox bug mentioned, you can do the following to get access to the headers you're looking for in FF:
Patch
https://github.com/angular/angular.js/blob/v1.2.0-rc.2/src/ng/httpBackend.js#L76
Add the headers you need. Currently it's only asking for the specified headers in that array for the FF work-around. You'd add something like:
simpleHeaders = ["Cache-Control", "Content-Language", "Content-Type",
"Expires", "Last-Modified", "Pragma", "Access-Control-Allow-Origin"];

How do I remove the default headers just for specific XHR requests in AngularJS?

99% of my ajax calls need a specific "X-API-TOKEN" to authenticate and communicate with my Rails REST API. But I'm also making a call to one thrid party API and I keep getting an error saying "Request header field X-API-TOKEN is not allowed by Access-Control-Allow-Headers."
Everything works fine if I delte the header right before the call, and a work around would be to delete and then re-add after the call, but is there an easier way than this:
apiToken = $http.defaults.headers.common["X-API-TOKEN"]
delete $http.defaults.headers.common["X-API-TOKEN"]
$http(
method: "GET"
url: 'http://...}}'
).success((data, status, headers, config) ->
).error (data, status, headers, config) ->
$http.defaults.headers.common["X-API-TOKEN"] = apiToken
Set the desire header/headers to undefined like this, then it will not affect the global settings.
$http( {
method: 'GET',
url: 'someurl',
headers: {
'X-API-TOKEN': undefined
}
}
)
The $http service config object allows you to override the http header send for a specific request. See config property headers.
This can take a list of headers or a function that return a list of headers. So for the non auth header request make a copy of the default headers remove the header you dont require and then make the request. You can store this for later use.
See $http documentation

Resources