javascript tutorial - [Solved-5 Solutions] How does access-control-allow-origin header work ? - javascript - java script - javascript array


Apparently, We have completely misunderstood its semantics. We thought of something like this:

  • A client downloads javascript code MyCode.js from http://siteA - the origin.
  • 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.

Well, We am wrong. It does not work like this at all. So, We have read Cross-origin resource sharing and attempted to read Cross-Origin Resource Sharing in w3c recommendation One thing is sure - We still do not understand how am We supposed to use this header. WE have full control of both site A and site B. How do We enable the javascript code downloaded from the site A to access resources on the site B using this header? P.S.

Solution 1:

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:

Access-Control-Allow-Origin: Modern browsers will not block cross-domain requests outright. If Site A requests a page from Site B, the browser will actually fetch the requested page on the network level and check if the response headers list Site A as a permitted requester domain. If Site B has not indicated that Site A is allowed to access this page, the browser will trigger the XMLHttpRequest's error event and deny the response data to the requesting JavaScript code. Non-simple requests What happens on the network level can be slightly more complex than explained above. If the request is a "non-simple", the browser first sends a data-less "preflight" OPTIONS request, to verify that the server will accept the request. A request is non-simple when either (or both):

using an HTTP verb other than GET or POST (e.g. PUT, DELETE)

using non-simple request headers; the only simple requests headers are:

  • Accept
  • Accept-Language
  • Content-Language
  • 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:

OPTIONS /somePage HTTP/1.1
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
click below button to copy the code. By JavaScript tutorial team

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:

Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
click below button to copy the code. By JavaScript tutorial team

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:

PUT /somePage HTTP/1.1
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }
click below button to copy the code. By JavaScript tutorial team

And the server sends back an Access-Control-Allow-Origin, just as it would for a simple request:

click below button to copy the code. By JavaScript tutorial team

Solution 2:

Cross-Origin Request Sharing - CORS (A.K.A. Cross-Domain AJAX request) is an issue that most web developers might encounter, according to Same-Origin-Policy, browsers restrict client JavaScript in a security sandbox, usually JS cannot directly communicate with a remote server from a different domain. In the past developers created many tricky ways to achieve Cross-Domain resource request, most commonly using ways are:

  • Use Flash/Silverlight or server side as a "proxy" to communicate with remote.
  • JSON With Padding ( JSONP).
  • Embeds remote server in an iframe and communicate through fragment or, refer here.

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.

The Mechanism

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

User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
click below button to copy the code. By JavaScript tutorial team

DomainB response headers

Cache-Control private
Content-Type application/json; charset=utf-8
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive
click below button to copy the code. By JavaScript tutorial team

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:

click below button to copy the code. By JavaScript tutorial team

If foo.aspx supports OPTIONS HTTP verb, it might return response like below:

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json
click below button to copy the code. By JavaScript tutorial team

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

Solution 3:

For cross origin sharing, set header: 'Access-Control-Allow-Origin':'*'; Php: header('Access-Control-Allow-Origin':'*'); Node: app.use('Access-Control-Allow-Origin':'*'); This will allow to share content for different domain.

Solution 4:

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:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
click below button to copy the code. By JavaScript tutorial team

Solution 5:

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:

header("Access-Control-Allow-Origin: *");
click below button to copy the code. By JavaScript tutorial team

If we are using external domains such as server, try this:

click below button to copy the code. By JavaScript tutorial team

Related Searches to javascript tutorial - How does access-control-allow-origin header work ?