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");
}]);
Related
I need to emulate some state in my developer utility, and for it I need to pass some special cookie to the http request which made via angular $http module.
Code for making http request looks simple:
if (condition){
var headers = getHeaders();
if (headers !== 'undefined'){
config['headers'] = headers;
}
}
return $http(config);
So looks like I should add some field to the this config. But I can't find any related data about this in $http docs.
I do not want to set cookie 'to the browser' becase I want to pass it only for some several requests performed asynchronously.
Is it real to nmake it with angular.js?
I have a REST API in GO language and the front-end in Angularjs , but when I get my resource in angular my custom header don't exist.
Controller:
Persons.query(
function (data, headerGetter, status) {
var headers = headerGetter();
console.log(headers["X-Total-Count"]); //PRINT: undefined
console.log(headers) //PRINT: {Content-Type:application/json;charset=utf-8}
console.log(data); //PRINT: [{name:'mr x', age:'67'}, ....]
},
function (error) {
console.error(error);
});
Model:
myApp.factory("Persons", function ($resource) {
return $resource(api_url+"/persons");
});
Response Chrome or Firefox, any client:
Access-Control-Allow-Methods:GET
Access-Control-Allow-Origin:*
Content-Length:1839
Content-Type:application/json; charset=utf-8
Date:Thu, 12 Mar 2015 21:53:54 GMT
X-Total-Count:150
You're making a request from a different domain than the one where your API is located, operation which is called Cross-site HTTP requests ( CORS )
In order to use custom headers you need to set another one called Access-Control-Expose-Headers
If you want clients to be able to access other headers, you have to
use the Access-Control-Expose-Headers header. The value of this header
is a comma-delimited list of response headers you want to expose to
the client.
This header lets a server whitelist headers that browsers are allowed
to access. For example:
Access-Control-Expose-Headers: X-My-Custom-Header,X-Another-Custom-Header
This allows the X-My-Custom-Header and
X-Another-Custom-Header headers to be exposed to the browser.
The way I do it in .NET ( I suppose it's kinda similar in Go):
HttpContext.Current.Response.AppendHeader("Access-Control-Expose-Headers", "X-Total-Pages, X-Records");
HttpContext.Current.Response.AppendHeader("X-Total-Pages", pages.ToString());
HttpContext.Current.Response.AppendHeader("X-Records", records.ToString());
And in AngularJS I'm getting headers like this :
var headers = headers();
headers['x-total-pages']
So this IS a CORS issue. Setting
Access-Control-Expose-Headers:"X-Total-Count"
in the server response solves your problem.
You will need to parse the response to a number:
parseInt(headers('X-Total-Count'), 10)
To overcome csrf attack, I have to send in csrf-token value in a header for every request by picking in the value from cookie as described here. Since this is to be done at every request, I am setting the default headers for $http in the main module's run function.
Now, If a new tab is opened for the same website, a new csrf token (in cookie) is issued by the server. Since the run function is run only once, the default header for csrf will be old one (for old tab), while the new csrf cookie will be sent to server, resulting in csrf-mismatch.
How to overcome this at a global level?
I want somehow to create a function which will be run everytime the $http is called, so that then I'll override the default headers.
Note: I do not want to set this header value for every $http request.
(Not that I think that it's relevant, but I'm using ui-router)
Edit
This is not just limited to csrf-token, I want to set some other headers too based on the logged in user, which has to be done dynamically (say when one user logs in, and logs out, then another user logs in).
you need to use http interceptor to do this on every request. read more about http interceptors here
below is one such example
module.factory('xsrfTokenInterceptor', function ($q, $http) {
return {
'response': function (response) {
var cookies = response.headers("Set-Cookie");
var token = someCrazyParsing(cookies);
$http.defaults.headers.common["X-CSRFToken"]=token;
return response || $q.when(response);
}
};
});
module.config(function($httpProvider){
$httpProvider.interceptors.push('xsrfTokenInterceptor')
})
How about headers $http(config) parameter.
$scope.getWithHeader = function(){
$http({
method: 'GET',
url: 'http://fiddle.jshell.net',
headers: {
'CustomHeader': 'HelloWorld'
}
}).success(function(){
console.log("success");
});
};
sample code on jsFiddle
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).
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")