2.4.3.16. Ошибки CORS и проблемы кросс-сайтовых AJAX-запросов

Важные моменты:

  • Заголовок Access-Control-Allow-Origin устанавливается на сервере, откуда сайт загружает ресурсы (не на сервере с сайтом).
  • Заголовок должен быть только один. При дублировании браузер будет возвращать ошибку его использования.

XMLHttpRequest — это API, который используется JS-скриптами для отправки запросов к серверу. Часто используется для создания интерактивных страниц с загрузкой данных на лету без перезагрузки страницы. В целях безопасности по умолчанию можно отправлять запросы только в пределах одного домена. Это обеспечивается с помощью использования CORS, который ограничивает все кросс-сайтовые HTTP-запросы.

Адрес сайта, с которого выполнялся запрос, указывается в заголовке Origin:

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

Пример ответа сервера на такой запрос:

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

В этом случае заголовок Access-Control-Allow-Origin разрешает запросы с указанного адреса и запрещает с других адресов. Именно из-за отсутствия такого заголовка может возникать проблема при кросс-доменных запросах. Принцип работы заголовка Access-Control-Allow-Origin состоит в том, чтобы запрещать или разрешать использовать ресурсы одного сайта в рамках других сайтов. Отсутствие заголовка Access-Control-Allow-Origin равноценно установке запрета на использование ресурсов.

Важные моменты:

  • Заголовки CORS добавляется на том сервере, откуда сайт загружает ресурсы. Если ваш сайт находится на нашем хостинге и загружает ресурсы со стороннего сервера, то добавлять заголовки нужно на стороннем сервере.
  • Добавление заголовков CORS на уровне PHP имеет больший приоритет, чем добавление на уровне .htaccess. При установке заголовков на уровне PHP и на уровне .htaccess будут действовать те, что установлены на уровне PHP.
  • Заголовки CORS, которые добавлены с помощью PHP или .htaccess не работают для статических файлов, так как такие файлы обрабатываются веб-сервером nginx. Для таких файлов используйте настройку CORS через панель управления.

В разделе «Настройки сайта» под списком статических файлов включите «Добавлять заголовок Access-Control-Allow-Origin: * для статических файлов» и сохраните изменения:

Не влияет на статические файлы.

На целевом сервере (куда сайт отправляет запросы) в PHP-скриптах загружаемых страниц добавьте такие директивы:

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');

* означает, что разрешены запросы с любых адресов. Если нужно разрешить запросы только с конкретного адреса, укажите его вместо * в формате http://example.com (если адресов несколько, продублируйте директиву для каждого адреса).

Не влияет на статические файлы и не переопределяет заголовки CORS, которые добавлены на уровне PHP.

На целевом сервере (куда сайт отправляет запросы) в файле .htaccess добавьте такие директивы:

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"

* означает, что разрешены запросы с любых адресов. Если нужно разрешить запросы только с конкретного адреса, укажите его вместо * в формате http://example.com (если адресов несколько, продублируйте директиву для каждого адреса).

Содержание

    (2)