16

I am attempting to provide a response to the HTTP OPTIONS method with an Access-Control-Allow-Origin header copying the contents of the Origin header in the request.

This is apparently not working, for reasons I can't figure out.

tl;dr: response from OPTIONS says:

Access-Control-Allow-Origin: http://10.0.0.105:9294

subsequent GET has:

Origin:http://10.0.0.105:9294

Chrome says:

Origin http://10.0.0.105:9294 is not allowed by Access-Control-Allow-Origin

WTF not?

More detail...

By looking in Chrome's developer tools window, the request headers are:

OPTIONS /user/kris HTTP/1.1
Host: 10.0.0.104:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.0.0.105:9294
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.75 Safari/537.1
Access-Control-Request-Headers: origin, x-requested-with, content-type, accept
Accept: */*
Referer: http://10.0.0.105:9294/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

The response headers are:

HTTP/1.0 200 OK
Date: Mon, 13 Aug 2012 11:23:45 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Length: 0
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS
Access-Control-Max-Age: 10
Access-Control-Allow-Origin: http://10.0.0.105:9294
Access-Control-Allow-Headers: X-Requested-With, Authorization, X-Huzu-User, Content-Type, Accept
Content-Type: text/html; charset=UTF-8

After jQuery sends its OPTIONS request and gets the above response, 2 odd things happen. The OPTIONS response (which is a 200) shows up in the developer console as an error:

OPTIONS http://10.0.0.104:8080/user/kris 200 (OK)

After which a GET request is rejected. Error in the console:

XMLHttpRequest cannot load http://10.0.0.104:8080/user/kris. Origin http://10.0.0.105:9294 is not allowed by Access-Control-Allow-Origin.

I can't see why not. What am I doing wrong?

hippietrail
  • 13,703
  • 15
  • 87
  • 133
scav
  • 1,005
  • 1
  • 9
  • 16
  • I don't have a minimal failing example of the jQuery code that would be any use to post here. Assume there is nothing odd about the javascript code, i.e. it's just a single jQuery get(), resulting in the OPTIONS request posted above. My question is: what's wrong with the response? – scav Aug 13 '12 at 11:57
  • Is it just me or is there a difference between the host url (10.0.0.104:8080) and the referer url (10.0.0.105:9294/) ? – rene Aug 13 '12 at 12:18
  • @rene yeah. My server is a python wsgi app running on my local machine (10.0.0.104:8080), and the cross-site testing is happening from a page I am loading from 10.0.0.105:9294. I don't know what effect the referer has on access control. Do you think it's relevant? If so, what do I do with it? – scav Aug 13 '12 at 13:14
  • If you start your browser in 10.0.0.4 you cann't load from 10.0.0.105. This header shoud have also 10.0.0.4:8080 as an allowed address: Access-Control-Allow-Origin: http://10.0.0.105:9294 – rene Aug 13 '12 at 13:36
  • @rene: 10.0.0.104:8080 isn't an origin of requests. It is the server itself. The javascript is loaded from 10.0.0.105:9294, so that is the origin. Or am I completely misunderstanding? Will try with browser on 10.0.0.105 and see if that helps. BTW I think some browsers (FF) only accept a single host in that header. – scav Aug 13 '12 at 14:25
  • it doesn't help running the browser on the same host as the javascript application. – scav Aug 13 '12 at 14:31
  • This is possibly the same as http://stackoverflow.com/questions/11580200/cors-request-isnt-allowed-despite-headers-being-set – scav Aug 13 '12 at 15:59

1 Answers1

29

OK, I think I've got it. It seems that proper handling of the pre-flight OPTIONS request is necessary, but NOT SUFFICIENT for cross-site resource requests to work.

After the OPTIONS request comes back with satisfactory headers, all responses to any subsequent requests to the same URL also have to have the necessary "Access-Control-Allow-Origin" header, otherwise the browser will swallow them, and they won't even show up in the debugger window.

So it will look like the browser cancelled the request because of some problem in the OPTIONS response, but actually, the browser is looking at the response headers from the real request and then rejecting them.

scav
  • 1,005
  • 1
  • 9
  • 16
  • Since u r done with ur query, Can u help me in this similar question ? http://stackoverflow.com/questions/11953132/no-response-obtained-while-implementing-cors – Prashant Singh Aug 14 '12 at 13:45
  • @scav +1 Can't thank you enough. You saved me hours of debugging! – alf Feb 23 '13 at 23:37
  • 1
    Also fails if the Access-Control-Allow-Origin:* you set in the actual response does not exactly match the one used in the pre-flight OPTIONS request. I was accidently adding it twice in asp dot net, once in IIS config and once in page load code, meant Access-Control-Allow-Origin:* occurred once in pre-flight OPTIONS but twice in the actual response so Chrome cancelled it. – Martin Belcher - AtWrk Jun 21 '13 at 16:00
  • 3
    just to second this... Chrome (v33 currently) seems to require the 304 response to have the `Access-Control-Allow-Origin: *` etc headers too, not just on the initial options response. Firefox (v27) doesn't seem to mind – Anentropic Mar 26 '14 at 18:48
  • Works a treat - I had one file requesting another, setting both with headers solved the problem :) – Rog Jun 17 '19 at 13:15
  • In my case, it was a 301 redirect in Lumen (e.g. `/api-endpoint/` to `/api-endpoint`) that was causing the error. – Robert Dundon Jun 17 '20 at 16:32
  • What is pre-flight OPTIONS? Worked with web for 15 years and never heard of it. You make a request and get a response.... This is very confusing – OZZIE Nov 16 '20 at 18:14