From what I've read about CORS, I understand it should work as follows:
Access-Control-Allow-Origin: *
), browser understands it's allowed to send main request and does it.I've set up a test for it like this:
Access-Control-*
headers in responsesimple HTML page (served by another server on another port) with the following script in it ($
stands for jQuery):
$.ajax({ type: "GET", crossDomain: true, url: "http://local.site.com/endpoint, success: function (data) { alert(data); }, error: function (request, error) { alert(error); } });
When I call this method, however, I see only one GET and no preflight OPTIONS request in the Network tab in both - Chrome 49 and Firefox 33.
Here are details of my GET request from Chrome:
Accept:*/* Accept-Encoding:gzip, deflate, sdch Accept-Language:en-US,en;q=0.8,ru;q=0.6 Connection:keep-alive Host:local.adform.com Origin:http://localhost:7500 Referer:http://localhost:7500/test-page.html User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
and corresponding response:
Access-Control-Allow-Headers:Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Origin:* Content-Length:2 Content-Type:text/plain; charset=utf-8 Date:Wed, 03 Aug 2016 10:53:19 GMT
Any thoughts on why my browser(s) don't send preflight request?
A CORS preflight OPTIONS request can be triggered just by adding a Content-Type header to a request — if the value's anything except application/x-www-form-urlencoded , text/plain , or multipart/form-data .
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method , Access-Control-Request-Headers , and the Origin header.
As pointed out by commentators, with GET browser doesn't always send preflight OPTIONS request. If preflight is indeed needed, one way to make browser to send it is to set custom header (e.g. "X-PINGOVER: pingpong" or whatever). Note, that server should also allow this request header by adding it to "Access-Control-Allow-Headers" response header.
My underlying goal was to pass cookies with domain a.com
to servers of a.com
, but from a page of another site(s) b.com
(common use case for this is tracking your users on 3rd party websites). It turns out to send cookies alongside the request a bit more work is involved.
On the client side (i.e. in JavaScript) one needs to enable cross domain request and allow passing credentials. E.g. the following request with jQuery worked for me:
$.ajax({ type: "GET", url: "http://example.com", xhrFields: { withCredentials: true // allow passing cookies }, crossDomain: true, // force corss-domain request success: function (data) { ... }, error: function (request, error) { ... } });
On the server side one needs to set 2 response headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: <requester origin>
where <requester origin>
is protocol + host + port of a website that performed a call. Note, that generic *
may not work in many browsers, so it makes sense for server to parse Referer
header of request and respond with specific allowed origin.
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