17

In our Angular app, we need to parse response headers of some $http.

In particular we need to parse some X-prefixed response headers, for example X-Total-Results: 35.

Opening the Network tab of the browser dev tools and inspecting the resource relative to the $http request, I verified that the response header X-Total-Results: 35 is present.

in the browser, the X-Total-Results header is available, but cannot be parsed in the Angular $http.

Is there a way to access in $http the 'raw' response and write our custom parser for the header?

$http.({method: 'GET', url: apiUrl,)
    .then( function(response){
        console.log('headers: ', response.headers());
        console.log('results header: ', response.headers('X-Total-Results'));
        // ...
    })

console output

headers: Object {cache-control: "no-cache="set-cookie"", content-type: "application/json;charset=utf-8"}

results header: null
klode
  • 10,821
  • 5
  • 34
  • 49
  • That's very weird, do you have any interceptors that might be modifying the returned promise? – yvesmancera Sep 04 '15 at 19:04
  • no, I do not have any interceptor – klode Sep 04 '15 at 19:13
  • @yvesmancera I also thought it weired! if the header is visible in the dev tool browser it means it should be accessible in angular, right? Or there might still be some problem with CORS or similar issues? The api is accessed cross domain and I have CORS on it I will update the question with the other headers. – klode Sep 04 '15 at 19:16
  • 1
    Now that you mention CORS, this is most definitely your problem: http://stackoverflow.com/questions/6112524/how-can-i-get-response-header-via-cross-domain-ajax – yvesmancera Sep 04 '15 at 19:17
  • Thanks I'll try that. Right now I have `Access-Control-Allow-Headers:X-Total-Results` and of course `Access-Control-Allow-Origin:*` – klode Sep 04 '15 at 19:21
  • @yvesmancera YESSSSSS `Access-Control-Expose-Headers` did the trick! – klode Sep 04 '15 at 19:24
  • Nice! Glad I could help! Mind if I post it as an answer? – yvesmancera Sep 04 '15 at 19:25
  • @yvesmancera do you know if wildcard can be used, something like `Access-Control-Expose-Headers: X-Total-*` – klode Sep 04 '15 at 19:27

2 Answers2

33

The reason you can't read the header on JavaScript but you can view it on the developer console is because for CORS requests, you need to allow the client to read the header.

Your server needs to send this header:

Access-Control-Expose-Headers:X-Total-Results

To answer your question in the comments, The Access-Control-Allow-Headers does not allow wildcards according to the W3 Spec

yvesmancera
  • 2,915
  • 5
  • 24
  • 33
  • This solves the problem. Thats interesting though, I thought that the developer console is a client.... Just by guessing I would have expected to be analogous to the angular/javascript client running in the same browser... clearly I am missing something. – klode Sep 04 '15 at 19:33
  • You can also view HTTPOnly cookies on the developer tools while you can't read them on JavaScript. – yvesmancera Sep 04 '15 at 19:34
  • saved my day, i had a Cors-Toggle chrome plugin, only few headers i was able to see because of this. – pTK Oct 27 '16 at 14:35
0

Use $httpProvider.interceptors you can intercept both the request as well as the response

for example

$httpProvider.interceptors.push(['$q', '$injector', function ($q, $injector) {
             return {
                 'responseError': function (response) {
                     console.log(response.config);
                 },
                 'response': function (response) {
                     console.log(response.config);
                 },
                 'request': function (response) {
                     console.log(response.config);
                 },
             };
         }]);

Update : You can retrive your headers info in call itself

$http.({method: 'GET', url: apiUrl)
    .then( (data, status, headers, config){
        console.log('headers: ', config.headers);
        console.log('results header: ', config.headers('X-Total-Results'));
        // ...
    })
maddygoround
  • 2,145
  • 2
  • 20
  • 32
  • the response object is available in the $http callback: `$http().then(function(response){ // response object available here })` the problem is it does not parse the results header I am interested in -- see question. – klode Sep 04 '15 at 18:58
  • 2
    your update code is buggy, did you mean .success(function(data, status, header, config) {}) ? – klode Sep 04 '15 at 19:00