2.20.16. Помилки CORS і проблеми крос-сайтовий AJAX-запитів

Важливі моменти:

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

XMLHttpRequest — це API, Який використовується JS-скриптами для відправки запитів до сервера. Досить часто він використовується для створення інтерактивних сторінок із завантаженням даних на льоту без перезавантаження сторінки. Використання такого API досить популярно, але в цілях безпеки за замовчуванням можна відправляти запити тільки в рамках одного домена. Така безпеку організована завдяки використанню 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 рівноцінно тому ж, що і вказівка заборони на використання ресурсів.

Вирішити проблему можна декількома способами:

Важливі моменти:

  • Додавання заголовків за допомогою PHP приоритетнее, ніж настройка через .htaccess. У такому випадку, якщо в рамках сайту в PHP-скриптах налаштована певна політика CORS, вказівка інших даних через .htaccess не змінить заголовки.
  • Способи реалізації передачі заголовків CORS за допомогою PHP і через .htaccess не будуть працювати для статичних файлів, так як їх обробка проводиться веб-сервером nginx. Щоб встановити настройки політики CORS для статичних файлів, потрібно скористатися першим способом.
  1. Для статичних файлів можна встановити параметр в налаштуваннях сайту, Який буде вказувати на дозвіл доступу з будь-якої адреси (Зверніть увагу: даний спосіб не діє на файли, які не вказані в списку статичних):
  2. В 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.

  3. У файлі .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"

    Для дозволу доступу кількома адресами їх потрібно вказати з нового рядка, наприклад так:

    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"
Зміст