2.4.3.16. CORS errors and problems of cross-site AJAX requests

Important points:

  • The Access-Control-Allow-Origin header is set on the server from which the site loads resources (not on the server with the site).
  • The header should be only one. If it is duplicated, the browser will return an error for its use.

XMLHttpRequest is an API that is used by JS scripts to send requests to the server. It is often used to create interactive pages with on-the-fly data loading without reloading the page. For security reasons, by default, requests can only be sent within the same domain. This is enforced through the use of CORS, which restricts all cross-site HTTP requests.

The address of the site from which the request was made is specified in the Origin header:

GET /example/ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
Accept: application/json, text/plain, */*
Referer: http://for.example.com/
Origin: http://for.example.com

An example of a server response to such a request:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Date: Sat, 01 Jan 2001 00:00:00 GMT
Server: nginx
Content-Length: 35
Connection: keep-alive
Access-Control-Allow-Origin: http://for.example.com

In this case, the Access-Control-Allow-Origin header allows requests from the specified address and denies requests from other addresses. It is the absence of such a header that can cause problems with cross-domain requests. The principle behind the Access-Control-Allow-Origin header is to deny or allow the use of resources from one site within other sites. The absence of the Access-Control-Allow-Origin header is equivalent to setting a prohibition on the use of resources.

Important points:

  • CORS headers are added on the server where the site loads resources from. If your site is on our hosting and loads resources from a third-party server, then headers should be added on the third-party server.
  • Adding CORS headers at the PHP level has higher priority than adding them at the .htaccess level. When headers are set at the PHP level and at the .htaccess level, those set at the PHP level will take effect.
  • CORS headers that are added using PHP or .htaccess don't work for static files, as such files are processed by the nginx web server. For such files, use the CORS setting via the control panel.
Only for static files.

In the "Site settings" section under the list of static files, enable "Add Access-Control-Allow-Origin header: * for static files" and save the changes:

Does not affect static files.

On the target server (where the site sends requests) in the PHP scripts of the pages to be loaded, add these directives:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Origin, Authorization');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');

* means that requests from any address are allowed. If you want to allow requests only from a specific address, specify it instead of * in the format http://example.com (if there are several addresses, duplicate the directive for each address).

Does not affect static files and does not override CORS headers that are added at the PHP level.

On the target server (where the site sends requests) in the .htaccess file, add these directives:

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

* means that requests from any address are allowed. If you want to allow requests only from a specific address, specify it instead of * in the format http://example.com (if there are several addresses, duplicate the directive for each address).

Content

    (2)