2
votes

I have a web server that accepts CORS requests. All responses from this server attach a custom header called X-Server-Version.

This custom header is listed in the Access-Control-Expose-Headers header in the CORS preflight response (see Cross Domain Resource Sharing GET: 'refused to get unsafe header "etag"' from Response). Using ngrep I have captured the response, which is shown below.

  HTTP/1.1 200 OK..Server: Apache-Coyote/1.1..Access-Control-Allow-Headers: accept, origin, content-type..Access-Control-Allow-Origin: *..Access-Control-Expose-Headers: X-Server-Version..X-Server-Version: 1.0-SNAPSHOT..Access-Control-Allow-Methods: POST..Content-Length: 0..Date: Wed, 10 Jul 2013 21:05:58 GMT.... 

This is a simple Javascript application that calls the CORS enabled endpoint.

<html>
    <head>
        <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
        <script>
            $.ajax({
              type: "POST",
              url: "http://server",
              data: '{"value":"whatever"}',
              success: function(data, textStatus, jqXHR) {
                console.log(jqXHR.getAllResponseHeaders());
              },
              error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.getAllResponseHeaders())
              },
              contentType:"application/json; charset=utf-8",
            });         
        </script>
    </head>
    <body>
    </body>
</html>

Whether this call succeeds or fails, getAllResponseHeaders() does not list this custom header for either Chrome 28 or Firefox 22. ngrep also confirms that the header is present in the response to the browser.

HTTP/1.1 200 OK..Server: Apache-Coyote/1.1..Access-Control-Allow-Origin: *..X-Server-Version: 1.0-SNAPSHOT..Content-Encoding: gzip..Content-Type: application/json..Content-Length: 7
  406..Date: Wed, 10 Jul 2013 21:09:11 GMT..

Does anyone know if it is possible to access the custom headers from a jQuery ajax call?

1
Please change your title to something that describes your issue and not just a set of tags.j08691

1 Answers

2
votes

The issue here is that the Access-Control-Expose-Headers header needs to be set in the CORS response, not the preflight (although you can have it in the preflight if for some reason you want to read custom headers in a OPTIONS request). This fact was not made particularly clear in any of the documentation I read, so I thought I would share my answer here.

So the response, as captured by ngrep, should look like

HTTP/1.1 400 Bad Request..Server: Apache-Coyote/1.1..Access-Control-Allow-Origin: *..Access-Control-Expose-Headers: X-Server-Version..X-Server-Version: 1.0-SNAPSHOT..Content-Enco
  ding: gzip..Content-Type: text/plain..Content-Length: 82..Date: Wed, 10 Jul 2013 23:03:37 GMT..

Once that header is returned, accessing customer headers works as you would expect.