CORS - Як зробити "попередній політ" повторним запитом?


94

Я намагаюсь зробити міждоменний HTTP-запит на сервіс WCF (який я маю). Я прочитав кілька прийомів роботи з обмеженнями сценаріїв міждоменного сценарію. Оскільки мій сервіс повинен вміщувати як GET, так і POST-запити, я не можу реалізувати динамічний тег сценарію, src якого є URL-адресою GET-запиту. Оскільки я вільний вносити зміни на сервері, я почав намагатися реалізувати вирішення, яке передбачає налаштування відповідей сервера на включення заголовка "Access-Control-Allow-Origin" та "попереднього польоту" із запитами та OPTIONS. Я отримав ідею з цієї посади: Робота з CORS

На стороні сервера мій веб-метод додає відповідь HTTP 'Access-Control-Allow-Origin: *'. Я можу бачити, що відповіді тепер включають цей заголовок. Моє запитання: Як я "передпольотно" запит (ВАРІАНТИ)? Я використовую jQuery.getJSON, щоб зробити запит GET, але браузер скасовує запит відразу з сумнозвісною:

Походження http: // localhost не дозволено Access-Control-Allow-Origin

Хтось знайомий з цією технікою CORS? Які зміни потрібно внести у клієнта для попереднього перегляду мого запиту?

Дякую!

Відповіді:


158

Під час запиту перед польотом ви повинні побачити наступні два заголовки: метод доступу-контроль-запит та доступ-контроль-запит-заголовки. Ці заголовки запитів просять у сервера дозволу зробити фактичний запит. Ваша відповідь перед польотом повинна підтвердити ці заголовки, щоб фактичний запит спрацював.

Наприклад, припустимо, що браузер робить запит із такими заголовками:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

Потім ваш сервер повинен відповідати такими заголовками:

Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

Зверніть особливу увагу на заголовок відповіді Access-Control-Allow-Headers. Значення цього заголовка має бути однаковими заголовками у заголовку запиту Access-Control-Request-Headers, і воно не може бути "*".

Після того, як ви надішлете цю відповідь на попередній запит, браузер зробить фактичний запит. Ви можете дізнатися більше про CORS тут: http://www.html5rocks.com/en/tutorials/cors/


Ви можете додати кілька доменів до Access-Control-Allow-Origin?
ботбот

@botbot Ви, мабуть, працювали до цього часу, але на випадок, коли іншим цікаво зробити цеAccess-Control-Allow-Origin: *
Стів Чемберс

2
Я, можливо, щось пропустив. Тож чи слід надсилати два запити XMLHttp? Один для передпольоту; перевірити відповідь на успіх, а потім надіслати фактичний запит?
Кангкан

14
@Kangkan вам не потрібно хвилюватися щодо надсилання запиту на попередній політ. Якщо запит потребує попереднього перельоту, браузер надішле його вам.
монсур

4
ДЯКУЙТЕ за біт "зверніть особливу увагу" ... який вирішив мою проблему з вузлом / expressjs, я зміг додати фільтр, щоб знайти ці запити перед //cors and preflight filtering app.all('*', function(req, res, next){.. //preflight needs to return exact request-header res.set('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); if ('OPTIONS' == req.method) return res.send(204);next(); });
польотом

0

Хоча ця тема датується 2014 роком, проблема все ще може бути актуальною для багатьох із нас. Ось як я справився з цим у контексті jQuery 1.12 / PHP 5.6:

  • jQuery надіслав свій запит XHR, використовуючи лише обмежені заголовки; було надіслано лише "Походження".
  • Запит на попередній політ не потрібен.
  • Сервер повинен був лише виявити такий запит і додати "Access-Control-Allow-Origin:". Заголовок $ _SERVER ['HTTP_ORIGIN'], виявивши, що це XHR перехресного походження.

Зразок коду PHP:

if (!empty($_SERVER['HTTP_ORIGIN'])) {
    // Uh oh, this XHR comes from outer space...
    // Use this opportunity to filter out referers that shouldn't be allowed to see this request
    if (!preg_match('@\.partner\.domain\.net$@'))
        die("End of the road if you're not my business partner.");

    // otherwise oblige
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
    // local request, no need to send a specific header for CORS
}

Зокрема, не додайте позначку, exit;оскільки попередній політ не потрібен.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.