Vitals:
Chrome Version 23.0.1271.64 Mac OS X 10.8.2
The Situation:
I have a web service exposed at https://api.myapi.com/... I would like to allow JavaScript applications to interact with this API. CORS feels like the obvious best fit (jsonp and friends being terrible, terrible hacks).
I can see in my Developer Tools that preflight requests are being sent out:
Request URL: https://api.myapi.com/someapi
Request Method: OPTIONS
Status Code: 200 OK
Request Headers
Accept: */*
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Access-Control-Request-Headers: origin, authorization, accept
Access-Control-Request-Method: GET
Connection: keep-alive
Host: api.myapi.com
Origin: http://prototypes.mycompany.com
Referer: http://prototypes.mycompany.com/somepage.html
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11
Response Headers
Access-Control-Allow-Headers: Accept,Authorization,Content-Length,Content-Type,Cookie
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS
Access-Control-Allow-Origin: http://prototypes.mycompany.com
Access-Control-Allow-Credentials: true
Connection: close
This looks great, in particular the response Access-Control-Allow-Origin
header seems to match the request Origin
header precisely.
Immediately afterwards, the actual request is attempted:
Request URL: https://api.myapi.com/someapi
Request Headers
Accept: application/json, text/javascript, */*; q=0.01
Authorization: <custom authentication scheme, removed>
Origin: http://prototypes.mycompany.com
Referer: http://prototypes.mycompany.com/somepage.html
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11
It then shows up as "Cancelled" and the following error is emitted:
XMLHttpRequest cannot load https://api.myapi.com/someapi. Origin http://prototypes.mycompany.com is not allowed by Access-Control-Allow-Origin.
I originally started with *
as my allowed origin, but that fails with precisely the same problem.
I have replicated this problem on Mobile Safari for iOS 5, and Firefox as well. In Firefox the behavior is even more confusing: The server responds 200 OK and then 6-7KB of data (which is what I expect). The client side log says that it got a 200 OK and ~300 bytes of data (with no response headers, no response at all...) and then triggers the "error" handler.
What am I missing?
Problem solved! I had to break out gdb
to figure it out though...
A proxy server was inserting its own CORS headers into the request. So the HTTP session had the headers specified multiple times. The security check was checking against the first header, which was "*", and fails the request. The request failure prints out the last header value, which looks correct.
Not very helpful, WebKit!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With