Apparently, We have completely misunderstood its semantics. We thought of something like this:
- The response header of MyCode.js contains Access-Control-Allow-Origin: http://siteB, which We thought meant that MyCode.js was allowed to make cross-origin references to the site B.
- The client triggers some functionality of MyCode.js, which in turn make requests to http://siteB, which should be fine, despite being cross-origin requests.
Access-Control-Allow-Origin is a CORS (Cross-Origin Resource Sharing) header. When Site A tries to fetch content from Site B, Site B can send an Access-Control-Allow-Originresponse header to tell the browser that the content of this page is accessible to certain origins. (An origin is a domain, plus a scheme and port number.) By default, Site B's pages are not accessible to any other origin; using the Access-Control-Allow-Origin header opens a door for cross-origin access by specific requesting origins. For each resource/page that Site B wants to make accessible to Site A, Site B should serve its pages with the response header:
using an HTTP verb other than GET or POST (e.g. PUT, DELETE)
using non-simple request headers; the only simple requests headers are:
- Content-Type (this is only simple when its value is application/x-www-form-urlencoded, multipart/form-data, or text/plain)
If the server responds to the OPTIONS preflight with appropriate response headers (Access-Control-Allow-Headers for non-simple headers, Access-Control-Allow-Methods for non-simple verbs) that match the non-simple verb and/or non-simple headers, then the browser sends the actual request. Supposing that Site A wants to send a PUT request for /somePage, with a non-simple Content-Type value of application/json, the browser would first send a preflight request:
Note that Access-Control-Request-Method and Access-Control-Request-Headers are added by the browser automatically; we do not need to add them. This OPTIONS preflight gets the successful response headers:
When sending the actual request (after preflight is done), the behavior is identical to how a simple request is handled. In other words, a non-simple request whose preflight is successful is treated the same as a simple request (i.e., the server must still send Access-Control-Allow-Origin again for the actual response). The browsers sends the actual request:
And the server sends back an Access-Control-Allow-Origin, just as it would for a simple request:
Those tricky ways have more or less some issues, for example JSONP might result in security hole if developers simply "eval" it, and #3 above, although it works, both domains should build strict contract between each other, it neither flexible nor elegant IMHO:) W3C had introduced Cross-Origin Resource Sharing (CORS) as a standard solution to provide a safe, flexible and a recommended standard way to solve this issue.
From a high level we can simply deem CORS is a contract between client AJAX call from domain A and a page hosted on domain B, a typical Cross-Origin request/response would be:
DomainA AJAX request headers
DomainB response headers
The blue parts We marked above were the kernal facts, "Origin" request header "indicates where the cross-origin request or preflight request originates from", the "Access-Control-Allow-Origin" response header indicates this page allows remote request from DomainA (if the value is * indicate allows remote requests from any domain). As We mentioned above, W3 recommended browser to implement a "preflight request" before submiting the actually Cross-Origin HTTP request, in a nutshell it is an HTTP OPTIONS request:
If foo.aspx supports OPTIONS HTTP verb, it might return response like below:
Only if the response contains "Access-Control-Allow-Origin" AND its value is "*" or contain the domain who submitted the CORS request, by satisfying this mandtory condition browser will submit the actual Cross-Domain request, and cache the result in "Preflight-Result-Cache". We blogged about CORS three years ago: AJAX Cross-Origin HTTP request
For cross origin sharing, set header:
This will allow to share content for different domain.
If we want just to test a cross domain application in which the browser blocks our request, then we can just open our browser in unsafe mode and test our application without changing our code and without making our code unsafe. From MAC OS we can do this from the terminal line:
If we are using PHP, try to add the following code at the beaning of the php file: if we are using localhost, try this:
If we are using external domains such as server, try this: