I am trying to make a cross domain HTTP request to WCF service (that I own). I have read several techniques for working with the cross domain scripting limitations. Because my service must accommodate both GET and POST requests I cannot implement some dynamic script tag whose src is the URL of a GET request. Since I am free to make changes at the server I have begun to try to implement a workaround that involves configuring the server responses to include the "Access-Control-Allow-Origin" header and 'preflight' requests with and OPTIONS request. I got the idea from this post : Getting CORS working
At the server side, my web method is adding 'Access-Control-Allow-Origin: *' to the HTTP response. I can see that responses do include this header now. My question is: How do I 'preflight' a request (OPTIONS)? I am using jQuery.getJSON to make the GET request but the browser cancels the request right away with the infamous:
Origin http://localhost is not allowed by Access-Control-Allow-Origin
Is anyone familiar with this CORS technique? What changes need to be made at the client to preflight my request?
Thanks!
CORS also relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual 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 .
Preflight is a web security feature implemented by the browser. For Chrome you can disable all web security by adding the --disable-web-security flag.
During the preflight request, you should see the following two headers: Access-Control-Request-Method and Access-Control-Request-Headers. These request headers are asking the server for permissions to make the actual request. Your preflight response needs to acknowledge these headers in order for the actual request to work.
For example, suppose the browser makes a request with the following headers:
Origin: http://yourdomain.com Access-Control-Request-Method: POST Access-Control-Request-Headers: X-Custom-Header
Your server should then respond with the following headers:
Access-Control-Allow-Origin: http://yourdomain.com Access-Control-Allow-Methods: GET, POST Access-Control-Allow-Headers: X-Custom-Header
Pay special attention to the Access-Control-Allow-Headers response header. The value of this header should be the same headers in the Access-Control-Request-Headers request header, and it can not be '*'.
Once you send this response to the preflight request, the browser will make the actual request. You can learn more about CORS here: http://www.html5rocks.com/en/tutorials/cors/
Although this thread dates back to 2014, the issue can still be current to many of us. Here is how I dealt with it in a jQuery 1.12 /PHP 5.6 context:
PHP Code sample:
if (!empty($_SERVER['HTTP_ORIGIN'])) { // Uh oh, this XHR comes from outer space... // Use this opportunity to filter out referers that shouldn't be allowed to see this request if (!preg_match('@\.partner\.domain\.net$@')) die("End of the road if you're not my business partner."); // otherwise oblige header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']); } else { // local request, no need to send a specific header for CORS }
In particular, don't add an exit;
as no preflight is needed.
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