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