2.4.3.16. CORS errors and problems of cross-site AJAX requests
Reason
Important points:
- The
Access-Control-Allow-Originheader 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.
Solution
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.
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:
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).
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).