CORS - Как выполнить предварительную проверку httprequest?

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

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

Источник http://localhost/ не разрешен Access-Control-Allow-Origin

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

Спасибо!

3 ответа

Решение

Во время предварительного запроса вы должны увидеть следующие два заголовка: 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/

Хотя эта ветка датируется 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; так как никакой предварительной проверки не требуется.

Решите проблему CORS, написав собственное промежуточное ПО в Node.js с помощью этих простых шагов.

don't need to set anything from the client, just a little change on the Node.js server will fix the problem.

создать промежуточное ПО:

      // in middleware/corsResolver.js

function corsResolver(req, res, next) {
    // Website you wish to allow to connect
    // running front-end application on port 3000
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); 
    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,Authorization');
    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);
    // Pass to next layer of middleware
    next();
}

module.exports = corsResolver;

теперь отредактируйте свой server.js (index.js или любой основной файл, который запускает ваш сервер node) и добавьте это промежуточное ПО:

      // server.js or indes.js 

const corsResolver = require('path/to/resolver-middleware')

app.use(corsResolver)  // -----------> applied middleware here


// other stuff
Другие вопросы по тегам