Стаття також доступна російською (перейти до перегляду).
Вступ
XMLHttpRequest - це API, що використовується JS-скриптами для надсилання запитів на сервер. Часто використовується для створення інтерактивних сторінок із завантаженням даних на льоту без перезавантаження сторінки. Використання такого API є дуже популярним, але з метою безпеки за замовчуванням можна надсилати запити лише в рамках одного домену. Така безпека організована завдяки використанню CORS, який обмежує всі крос-сайтові HTTP-запити.
З появою специфікації Cross Origin Resource Sharing (CORS), яка тепер є кандидатом у рекомендації W3C, розробники веб-додатків отримали підтримуваний браузером механізм для безпечного виконання XmlHttpRequests в іншому домені.
На момент написання цієї статті ми нарешті можемо сказати, що CORS підтримується всіма основними браузерами. Спочатку він з'явився у Firefox 3.5, Safari 4 та Chrome 3. Internet Explorer 10 тепер має вбудовану підтримку.
Симптоми проблеми.
У вікні браузера з'являється одне з таких повідомлень:
- Помилка завантаження заголовка No Access-Control-Allow-Origin.
- Запит між джерелами заблокований: політика «Те саме джерело» забороняє читання віддаленого ресурсу... Причина: заголовок CORS «Access-Control-Allow-Origin» відсутня.
- Не вдалося завантажити відповідь на попередній запит, не пройшов перевірку керування доступом: у запитаному ресурсі відсутній заголовок Access-Control-Allow-Origin.
Одним із ключових слів, яке зазвичай згадується в повідомленнях, є Access-Control-Allow-Origin.
Умови
Веб-застосунок на основі браузера намагається виконати виклик «незалежно від джерела», щоб отримати «загальний ресурс» від зовнішньої веб-служби. Це називається запитом CORS (Cross-Origin-Resource-Sharing).
Існує стандарт CORS на основі браузера, який керує такими дзвінками з різних джерел. Якщо певні умови не виконуються, виникають помилки, вказані вище.
Рішення
Це не обов'язково помилка, так як це може бути варіант використання, який веб-додаток користувача та зовнішня віддалена служба навмисно забороняють.
Коли одне джерело (www.ursprung1.com) запитує інше джерело (www.ursprung2.com), це називається запитом між джерелами. Щоб цей запит працював, мають бути виконані певні умови. Викликана зовнішня служба (www.origin2.com) має повернути у своїй відповіді HTTP-заголовок Access-Control-Allow-Origin.
Якщо зовнішня служба не поверне цей заголовок, відповідність браузера специфікації CORS зупинить запит і поверне одну з наведених вище помилок.
Що таке Cors перехресний запит?
Якщо скрипт на вашій сторінці запускається з домену mydomain.com і хотів би запитати ресурс через XmlHttpRequest або XDomainRequest з домену otherdomain.com, це запит з іншого джерела. Історично склалося так, що з міркувань безпеки ці типи запитів були заборонені браузерами.
Прості запити
Для простих міжсайтових запитів (тобто GET і POST, які не встановлюють налаштовувані заголовки, а тіло запиту являє собою звичайний текст або дані форми) браузер просто включає додаткові заголовки Origin і Referrer, що вказують запитуючий домен.
Зверніть увагу, що браузер буде включати заголовок Origin тільки в тому випадку, якщо запит є перехресним. Адже основна причина – відсутня заголовок – cors access control allow origin.
Коли браузер побачить, що значення Access-Control-Allow-Origin відповідає домену сторінки, він дозволить обробку відповіді. Сервер може встановити значення * у цьому заголовку, щоб вказати, що це загальнодоступний ресурс, який допускає будь-яке походження.
Попередні запити
Попередній запит використовує метод запиту OPTIONS для перевірки того, що сервер підтримує CORS host та підтримує тип запиту, який клієнт хотів би надіслати.
Запити з обліковими даними
Браузер не надсилатиме файли cookie або дані автентифікації HTTP у міждоменному запиті XmlHttpRequest. Клієнтський застосунок повиннен вказати, що вони повинні бути відправлені, задавши властивість withCredentials запиту XmlHttpRequest або XDomainRequest. За промовчанням це значення дорівнює false і не встановлене.
Зверніть увагу, що для цього необхідно використовувати jQuery 1.5.1+, оскільки попередні версії jQuery не передавали властивість withCredentials у власний XmlHttpRequest.
Обов'язкова примітка до Internet Explorer
Internet Explorer 8 та 9 мають обмежену підтримку CORS. А саме:
- Підтримуються лише GET та POST із типом вмісту звичайний/текст.
- Він не підтримує попередньої перевірки
- До запиту не можна додавати налаштовувані заголовки
- Запити облікових даних не підтримуються
- Запити повинні бути спрямовані на ту ж схему, що й сторінка хостингу.
Internet Explorer 10 має вбудовану підтримку CORS. Однак на момент написання цієї статті IE 10 підтримує лише запити з обліковими даними між доменами, які мають співпадаюче доменне ім'я другого рівня, наприклад, a.mydomain.com запитує b.mydomain.com. Поки неможливо надсилати облікові дані між mydomain.com та otherdomain.com.
Тестування
Чудовий ресурс для тестування запитів CORS можна знайти на веб-сайті test.cors.org. Цей тестовий сайт дозволяє:
- Надсилати запити CORS на віддалений сервер для перевірки його можливостей.
- Надсилання запитів CORS на тестовий сервер для вивчення функцій CORS.
Якщо ваш веб-додаток повинен працювати в браузерах, які не підтримують CORS, або взаємодіяти з серверами, які не підтримують CORS, то існує кілька альтернатив CORS, які використовувалися для усунення обмеження зв'язку між джерелами.
Який початковий URL виклику (тобто джерело)? Іноді це можна знайти у повідомленні про помилку.
Яка URL-адреса вилучається із зовнішньої служби? Іноді це можна знайти у повідомленні про помилку консолі.
Що отримується і чому? Це файл PNG? Скрипт, CSS чи файл шрифту? Що саме витягується і навіщо використовується? Це може пролити світло на варіант використання і показати, чому актив так важливий у цьому віддаленому місці.
Чи цей зовнішній ресурс потребує аутентифікації? Якщо потрібна переадресація, заголовок відповіді Access-Control-Allow-Origin може не повертатися, і виклик завершиться помилкою. Скопіюйте URL-адресу ресурсу прямо в нову вкладку інкогніто у браузері. Це може бути гарною перевіркою того, чи можна отримати доступ до нього за загальних обставин, але це не гарантує, що він буде працювати в коді веб-додатку.
Чи бачите ви виклик методу HTTP OPTIONS на вкладці «Мережа» браузера? Якщо налаштовувані заголовки запиту, автентифікація або інші умови, присутні в запиті між джерелами, браузер виконує додатковий HTTP-дзвінок. Це також відомо як «передполітний виклик». Це явно не вказано у коді веб-застосунку. Браузер у фоновому режимі створює його та робить частиною специфікації CORS.
Коли виконується виклик OPTIONS, у відповідь від цього виклику повинні бути включені певні значення, щоб він був успішним і був виконаний фактичний HTTP-виклик до ресурсу. Якщо OPTIONS завершується невдало, ресурс не виймається і в консолі браузера з'являється помилка CORS.
Запишіть, коли ви бачите виклик OPTIONS. Також зверніть увагу, чи відбувається виклик з переадресацією (стан 302) безпосередньо перед викликом OPTIONS.
Якщо під час виклику OPTIONS відбувається переадресація, виклик OPTIONS, швидше за все, завершиться помилкою. Це означає, що виклик ресурсу завершиться помилкою CORS.
Яким є варіант використання для надання зовнішніх ресурсів? З'ясуйте, чому цей зовнішній ресурс витягується в першу чергу. Це може бути важливим для рішень або змін.
Генерація HAR-файлу. Якщо ви можете отримати миттэвий знімок невдалого виклику та подій до та після нього, ви зможете краще усунути проблему та уникнути необхідності її відтворення користувачем. Заголовки у запитах та відповідях можуть бути перевірені разом з OPTIONS викликами та переадресаціями!
Підписуйтесь на наш телеграм–канал https://t.me/freehostua, щоб бути в курсі нових корисних матеріалів.
Дивіться наш канал Youtube на https://www.youtube.com/freehostua.
Ми у чомусь помилилися, чи щось пропустили?
Напишіть Про це у коментарях, ми з задоволенням відповімо та обговорюємо Ваші зауваження та пропозиції.
Дата: 01.02.2023 Автор: Євген
|
|
Авторам статті важлива Ваша думка. Будемо раді його обговорити з Вами:
comments powered by Disqus