We have been noticing the same issue, where the server is sending the correct CORS headers, but the browser fails because it thinks the CORS requirements are not being met. More interestingly, in our case, it only happens on some AJAX calls in the same browser session, but not all.
Working theory...
Clearing the browser cache solves the problem in our case -- My current working theory is that this has something to do with cookies being set by the cross origin server. I noticed in your scenario, there is a cookie being set as part of the response to the pre-flight OPTIONS request. Have you tried making that server not set any cookies for requests coming from a different origin?
However, we've noticed that in some cases, the problem re-appeared after resetting the browser. Also, running the browser in in-private mode causes the problem to go away, pointing to some problem to do with what's in the browser cache.
For reference, here is my scenario (I almost posted this as a new question in SO, but putting it here instead):
We ran into a bug where some CORS GET requests made via jQuery.ajax were failing. In a given browser session, we see the pre-flight OPTIONS request go through, followed by the actual request. In the same session, some requests go through and others fail.
The sequence of requests and responses in the browser network console look like below:
First the OPTIONS pre-flight request
OPTIONS /api/v1/users/337/statuses
HTTP/1.1 Host: api.obfuscatedserver.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.10.8.84:3003
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, origin, x-csrf-token, auth
Accept: */* Referer: http://10.10.8.84:3003/
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
Which gets a response like,
HTTP/1.1 200 OK
Date: Tue, 06 Aug 2013 19:18:22 GMT
Server: Apache/2.2.22 (Ubuntu)
Access-Control-Allow-Origin: http://10.10.8.84:3003
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, origin, x-csrf-token, auth
X-UA-Compatible: IE=Edge,chrome=1
Cache-Control: no-cache
X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c
X-Runtime: 0.001344
X-Rack-Cache: invalidate, pass
X-Powered-By: Phusion
Passenger 4.0.2
Status: 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
Then the actual GET request,
GET https://api.obfuscatedserver.com/api/v1/users/337
HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://10.10.8.84:3003/
Origin: http://10.10.8.84:3003
X-CSRF-Token: xxxxxxx
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
auth: xxxxxxxxx
Which gets an error in the browser console like,
XMLHttpRequest
cannot load https://api.obfuscatedserver.com/api/v1/users/337.
Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin.
Additional Debugging
I can replay the same sequence via curl, and I see valid responses coming from the server. i.e. they have the expected CORS headers that should let the requests go through.
Running the same scenario in an in-private / incognito browser window did not reproduce the problem. This lead me to try clearing the cache, and that made the problem go away too. But after a while, it came back.
The issue was reproducing on iPhone safari as well as on Chrome on OSX desktop.
What I really need help with
I'm suspecting there are some cookies set in the cross-origin domain that are getting involved here and potentially exposing a bug in the browser. Are there tools or breakpoints I can set in the browser (native stack?) to try and debug this further? A breakpoint in the code that evaluates the CORS policy would be ideal.