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-Origin response 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: http://siteA.com
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" request, 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);
- 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
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
Note that Access-Control-Request-Method
and Access-Control-Request-Headers
are added by the browser automatically; you do not need to add them. This OPTIONS preflight gets the successful response headers:
Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
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
Origin: http://siteA.com
Content-Type: application/json
{ "myRequestContent": "JSON is so great" }
And the server sends back an Access-Control-Allow-Origin
, just as it would for a simple request:
Access-Control-Allow-Origin: http://siteA.com
See Understanding XMLHttpRequest over CORS for a little more information about non-simple requests.
The Origin header
When this header is added ?
During the header's stage, before the document's body is sent (after open
, before send
).
Is it added when a browser (that support CORS) is doing a request ? ( cross domain or non-cross-domain?)
It is added when the origin doesn't match the page from which the XMLHttpRequest is created, but may also be sent in a same-origin request.
Or does it added automatically when the browser "sees" that the request target origin is different from the current origin...
Yes.
However, the browser will always send the required Origin headers when necessary.
This is part of the XMLHttpRequest spec; if you're making a cross-domain request, in the request headers an extra header is sent. This header is e.g. Origin: http://www.stackoverflow.com
and is appended by a standards-following browser without user interaction.
You can read more on the specification in MozillaWiki's Security section, WHATWG and html5.org. It is implemented by (that I know of) FireFox and Google Chrome. I don't believe it is part of W3C yet. Further do not assume the origin header is true, as it can be set manually by modified borwsers or other software.
Best Answer
Yes, you need to have the header
Access-Control-Allow-Origin: http://domain.example:3000
orAccess-Control-Allow-Origin: *
on both the OPTIONS response and the POST response. You should include the headerAccess-Control-Allow-Credentials: true
on the POST response as well.Your OPTIONS response should also include the header
Access-Control-Allow-Headers: origin, content-type, accept
to match the requested header.