CORS - Как "предварять" http-запрос?

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

На стороне сервера мой веб-метод добавляет к HTTP-ответу "Access-Control-Allow-Origin: *". Я вижу, что ответы теперь включают этот заголовок. Мой вопрос: как я "предваряю" запрос (ОПЦИИ)? Я использую jQuery.getJSON, чтобы сделать запрос GET, но браузер немедленно отменил запрос с печально известным:

Происхождение http://localhost не разрешено Access-Control-Allow-Origin

Кто-нибудь знаком с этой техникой CORS? Какие изменения необходимо сделать на клиенте для предполнения моего запроса?

Спасибо!

Ответ 1

Во время предпродажного запроса вы должны увидеть следующие два заголовка: Access-Control-Request-Method и Access-Control-Request-Headers. Эти заголовки запросов запрашивают у сервера разрешения на выполнение фактического запроса. Ваш предполетный ответ должен подтвердить эти заголовки, чтобы фактический запрос работал.

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

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/

Ответ 2

Хотя этот поток относится к 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\[email protected]'))
        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;, поскольку не требуется предварительный просмотр.