Saturday, December 9, 2017

XMLHttpRequest cannot load. No 'Access-Control-Allow-Origin' header is present on the requested resource

XMLHttpRequest cannot load. No 'Access-Control-Allow-Origin' header is present on the requested resource

APIs are the threads that let you stitch together a rich web experience. But this experience has a hard time translating to the browser, where the options for cross-domain requests are limited to techniques like JSON-P (which has limited use due to security concerns) or setting up a custom proxy (which can be a pain to set up and maintain).

Cross-Origin Resource Sharing (CORS) is a W3C spec that allows cross-domain communication from the browser. By building on top of the XMLHttpRequest object, CORS allows developers to work with the same idioms as same-domain requests.

The use-case for CORS is simple. Imagine the site alice.com has some data that the site bob.com wants to access. This type of request traditionally wouldn’t be allowed under the browser’s same origin policy. However, by supporting CORS requests, alice.com can add a few special response headers that allows bob.com to access the data.

As you can see from this example, CORS support requires coordination between both the server and client. Luckily, if you are a client-side developer you are shielded from most of these details. The rest of this article shows how clients can make cross-origin requests, and how servers can configure themselves to support CORS.

Method 1:

On the remote server, add:

<?php
header('Access-Control-Allow-Origin: http://symfony.cent-dev.local');
#header('Access-Control-Allow-Headers: X-Requested-With');
#header('Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS');
?>

Then, go observe the response in the browser at client side. You will see the three lines above.

Method 2:

On the remote server, edit your Apache configuration file:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: http://symfony.cent-dev.local
</ifModule>

Note: you can replace http://symfony.cent-dev.local to a wildcard *.

Note: and don't forget to load module: a2enmod headers

Method 3:

Add a proxy script on your server, ex: proxy.php then having your client side script to access the proxy.php script.

The proxy.php script then send the request to the remote server.

Method 4:

On your server, set up proxy on Apache:

<LocationMatch "/api">
   ProxyPass http://remote-server.com:8000/api/
   #Header add "Access-Control-Allow-Origin" "*"
   Header add "Access-Control-Allow-Origin" "http://symfony.cent-dev.local"
</LocationMatch>

Note: You need to enable mod_proxy and mod_headers.

Reference:

http://www.html5rocks.com/en/tutorials/cors/
http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-cors
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
http://www.andlabs.org/html5.html
https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity

No comments: