Зазвичай запит XMLHttpRequest може робити запит тільки в рамках поточного сайту. При спробі використовувати інший домен / порт / протокол - браузер видає помилку.
Існує сучасний стандарт XMLHttpRequest. він ще в стані чернетки, але передбачає крос-доменні запити і багато іншого.
Більшість можливостей цього стандарту вже підтримуються всіма браузерами, але на жаль, не в IE9-.
Втім, частково крос-доменні запити підтримуються, починаючи з IE8, тільки замість XMLHttpRequest потрібно використовувати об'єкт XDomainRequest.
Розберемо крос-доменні запити на прикладі коду:
- Ми створюємо XMLHttpRequest і перевіряємо, чи підтримує він подія onload. Якщо немає, то це старий XMLHttpRequest. значить це IE8,9, і використовуємо XDomainRequest.
- Запит на інший домен відсилається просто зазначенням відповідного URL в open. Він обов'язково повинен бути асинхронним, в іншому - ніяких особливостей.
Крос-доменні запити проходять спеціальний контроль безпеки, мета якого - не дати злим хакерам ™ завоювати інтернет.
Серйозно. Розробники стандарту передбачили все заслони, щоб «злий хакер» не зміг, скориставшись новим стандартом, зробити щось принципово відмінне від того, що і так міг раніше і, таким чином, «зламати» який-небудь сервер, що працює по-старому стандарту і не очікує нічого принципово нового.
Давайте, на хвилиночку, уявімо, що з'явився стандарт, який дає, без обмежень, можливість робити будь-якій сторінці HTTP-запити куди завгодно, які завгодно.
Як зможе цим скористатися злий хакер?
Специфікація CORS накладає спеціальні обмеження на запити, які покликані не допустити подібного апокаліпсису.
Запити в ній діляться на два види.
Простими вважаються запити, якщо вони задовольняють наступним двом умовам:
- Простий метод. GET, POST або HEAD
- Прості заголовки - тільки зі списку:
- Accept
- Accept-Language
- Content-Language
- Content-Type зі значенням application / x-www-form-urlencoded. multipart / form-data або text / plain.
«Непростими» вважаються всі інші, наприклад, запит з методом PUT або з заголовком Authorization не підходить під обмеження вище.
Принципова різниця між ними полягає в тому, що «простий» запит можна сформувати і відправити на сервер і без XMLHttpRequest, наприклад за допомогою HTML-форми.
А ось запити з нестандартними заголовками або з методом DELETE в такий спосіб не створити. Тому старий сервер може бути до них не готовий. Або, наприклад, він може вважати, що такі запити веб-сторінка в принципі не вміє надсилати, значить вони прийшли з привілейованого додатки, і дати їм занадто багато прав.
Тому при посилці «непростих» запитів потрібно спеціальним чином запитати у сервера, чи згоден він в принципі на подібні крос-доменні запити чи ні? І, якщо сервер не відповість, що згоден - значить, немає.
У специфікації CORS, як ми побачимо далі, є багато деталей, але всі вони об'єднані єдиним принципом: нові можливості доступні тільки з явного згоди сервера (за замовчуванням - немає).
У крос-доменний запит браузер автоматично додає заголовок Origin. що містить домен, з якого здійснено запит.
Сервер повинен, зі свого боку, відповісти спеціальними заголовками, чи дозволяє він такий запит до себе.
![Xmlhttprequest крос-доменні запити (запити) Xmlhttprequest крос-доменні запити](https://images-on-off.com/images/148/xmlhttprequestkrossdomenniezaprosi-7fa242fd.png)
Тобто, відповідь сервера може бути приблизно таким:
Якщо Access-Control-Allow-Origin немає, то браузер вважає, що дозвіл не отримано, і завершує запит з помилкою.
Що може зробити хакер, використовуючи такі запити?
Описані вище обмеження призводять до того, що запит повністю безпечний.
Дійсно, зла сторінка може сформувати будь-GET / POST-запит і відправити його, але без дозволу сервера відповіді вона не отримає.
У IE9- використовується XDomainRequest. який представляє собою урізаний XMLHttpRequest.
На нього діють обмеження:
Сучасний стандарт XMLHttpRequest передбачає кошти для подолання цих обмежень, але на момент виходу IE8 вони ще не були опрацьовані, тому їх не реалізували. А IE9 виправив деякі помилки, але в загальному не додав нічого нового.
Тому на сайтах, які хочуть підтримувати IE9-, то на практиці крос-доменні запити рідко використовують, вважаючи за краще інші способи крос-доменної комунікації. Наприклад, динамічно створюваний тег SCRIPT або допоміжний IFRAME з іншого домену. Ми розберемо ці підходи в наступних розділах.
Як дозволити крос-доменні запити від довіреної сайту в IE9-?
Дозволити крос-доменні запити для «довірених» сайтів можна в налаштуваннях IE, у вкладці «Безпека», включивши пункт «Доступ до джерел даних за межами домену».
Зазвичай це робиться для зони «Надійні вузли», після чого в неї вноситься довірений сайт. Тепер він може робити крос-доменні запити XMLHttpRequest.
Цей спосіб можна застосувати для корпоративних сайтів, а також в тих випадках, коли відвідувач свідомо вам довіряє, але чомусь (комп'ютер на роботі, адмін забороняє ставити інший браузер?) Хоче використовувати саме IE. Наприклад, він може пропонуватися в якості додаткової інструкції «як змусити цей сервіс працювати під IE».
В IE дозволений інший порт
У крос-доменні обмеження IE не включені порт.
Це дозволяє вирішити деякі завдання, пов'язані із взаємодією різних сервісів в рамках одного сайту. Але тільки для IE.
Розширені можливості, описані далі, підтримуються всіма сучасними браузерами, крім IE9-.