7

I am making cross domain ajax requests with html data type. They work OK as I include

Access-Control-Allow-Origin

in the response from the server. Problem is I need to get certain headers from the server's response and whatever I do, response headers apart from "content type" return null.

jQuery does the request, retrieves the response including headers (I can see it from the traffic) but it doesn't parse it.

I have tried using

crossDomain: true

It didn't help. Here is the sample response from the server.

Access-Control-Allow-Origin:*
Cache-Control:private
Content-Encoding:gzip
Content-Length:514
Content-Type:text/html; charset=utf-8 
X-MYRESPONSEHEADER:1

If requesting and responding document are on same server

 success: function (data, status, xhr) {
        totalRows = xhr.getResponseHeader("X-MYRESPONSEHEADER");

works fine. I have also tried to assign $.ajax to a variable like

var jQxhr = $.ajax(.....

I don't see why it wouldn't be parsed since jQuery actually makes the request and gets the response

Any ideas? Am I missing something?

Update or dragon's comment

Headers sent to request

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-MYRESPONSEHEADER
Access-Control-Allow-Methods: POST
Access-Control-Allow-Methods: GET
X-MYRESPONSEHEADER: 24
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 29 Feb 2012 11:34:21 GMT

Content-Length: 514

nLL
  • 5,662
  • 11
  • 52
  • 87

4 Answers4

2

If you're using aws s3 (and I assume this is applicable otherwise), the problem is possibly a missing CORS configuration tag. I ran in to a similar problem with missing. Here's my completed configuration:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>http://localhost:3000</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
        <ExposeHeader>*</ExposeHeader>
    </CORSRule>
</CORSConfiguration>

AllowedHeader sets the Access-Control-Request-Headers header, and ExposeHeader sets Access-Control-Expose-Headers header, without which the browser wont allow javascript to use the returned headers.

Steven Soroka
  • 19,404
  • 4
  • 52
  • 40
  • S3 gives error: ExposeHeader "*" contains wildcard. We currently do not support wildcard for ExposeHeader. – Dane W Jan 30 '13 at 18:27
  • Same problem -- didn't work with wildcard. In my case though I just needed the browser to expose the Location header and this answer worked with the header explicitly defined. – Ben Alavi May 15 '15 at 22:55
2

To read headers other than content-type in the server's response, the server must supply Access-Control-Expose-Headers, eg:

Access-Control-Expose-Headers: X-MYRESPONSEHEADER 

@dragon's answer mentionsAccess-Control-Allow-Headers which only controls which headers the client can send when making a request to the server.

Useful CORS tutorial here: http://www.html5rocks.com/en/tutorials/cors/

tekumara
  • 8,357
  • 10
  • 57
  • 69
2

You need to add another CORS-specific header in the server response, Access-Control-Allow-Headers. In this case,

Access-Control-Allow-Headers: X-MYRESPONSEHEADER

Ref: https://developer.mozilla.org/en/http_access_control#Access-Control-Allow-Headers

dragon
  • 1,747
  • 15
  • 18
  • it didn't work for me. do you think i need to assign $.ajax to a variable? – nLL Feb 28 '12 at 16:23
  • Is your [HTTP OPTIONS request](https://developer.mozilla.org/en/http_access_control#Preflighted_requests) returning the appropriate Access-Control headers? – dragon Feb 28 '12 at 20:18
  • @nLL Could you add the full request/response headers for each of the two requests made? First request is OPTIONS and second is GET/POST. – dragon Feb 29 '12 at 22:30
  • I don't do any OPTIONS request manually and don;t see jQuery doing it. Is it part of the process? If so how would jQuery know about it – nLL Feb 29 '12 at 23:17
  • It is a part of the process, and the browsers do it in certain cases before making cross-domain calls, as per the specifications. Please note that jQuery doesn't make this call -- browsers do. For more, https://developer.mozilla.org/en/http_access_control#Preflighted_requests – dragon Mar 01 '12 at 20:57
  • Im testing it on Chrome and don;t see any request from browser. Anyways I'll have to dig in deeper. Thanks for your time – nLL Mar 01 '12 at 21:04
  • The Access-Control-Allow-Headers only controls which request headers can be sent. It doesn't influence response headers. – Tal Lev-Ami Feb 28 '13 at 10:09
0

Here is configuration that worked for me. I've put it in java Filter filter method. Some headers need to be send only with preflight request (method = "OPTIONS"), there is no need to send them every time.

Please notice that for "Authorization" header the "Access-Control-Allow-Credentials" is also required.

 HttpServletResponse resp = (HttpServletResponse) res;
 resp.addHeader("Access-Control-Allow-Origin", "http://your_domain:your_port");
 resp.addHeader("Access-Control-Allow-Credentials", "true");
 if (((HttpServletRequest) req).getMethod().equals("OPTIONS")) {
       resp.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
      resp.addHeader("Access-Control-Allow-Headers", "Authorization");
      return;
  }
vinga
  • 1,912
  • 20
  • 33