CORS errors and cross-site AJAX request issues

Important points:

  • heading Access-Control-Allow-Origin installed on the server hosting the resource requested by the site.
  • heading Access-Control-Allow-Origin must return only one... If a header is duplicated, the browser will return an error using it.

XMLHttpRequest is an API that is used by JS scripts to send requests to the server. Quite often it is used to create interactive pages with data loading on the fly without reloading the page. Using such an API is quite popular, but for security reasons, by default, you can only send requests within the same domain. This security is organized through the use of CORSwhich limits all cross-site HTTP requests.

To indicate the address from which the request was made, the header is used Origin... This header looks something like this:

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

The response from the server to such a request may be something like this:

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 title Access-Control-Allow-Origin allows requests from the specified address and denies from other addresses. It is because of the absence of such a header that a problem can arise with cross-domain requests. How the header works Access-Control-Allow-Origin is to prohibit or allow the use of the resources of one site within other sites. Lack of title Access-Control-Allow-Origin is equivalent to specifying a ban on the use of resources.

There are several ways to solve the problem:

Important points:

  • Adding headers with PHP takes precedence over setting through .htaccess. In this case, if a certain CORS policy is configured within the site in PHP scripts, specifying other data via .htaccess will not change the headers.
  • Ways to Implement CORS Header Passing with PHP and via .htaccess will not work for static files, since they are processed by the nginx web server. To set the CORS policy settings for static files, you need to use the first method.
  1. For static files you can set the parameter in site settings, which will indicate permission to access from any address (note: this method does not work for files that are not listed in the static list):
  2. In PHP scripts of loaded pages (for which requests are made) you need to specify the following 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');

    In this case, requests will be allowed from any address without any protection. Instead of the symbol * you can specify the address of the site from which requests will be allowed, in the form http://example.com.

  3. In the .htaccess file, you need to specify the directives for adding headers:
    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"

    To allow access to several addresses, they must be specified on a new line, for example, like this:

    Header add Access-Control-Allow-Origin "http://some.for.example.com"
    Header add Access-Control-Allow-Origin "http://for.example.com"
    Header add Access-Control-Allow-Origin "http://example.com"