Почему добавление заголовков CORS к маршруту OPTIONS не позволяет браузерам получать доступ к моему API? - PullRequest
590 голосов
/ 15 августа 2011

Я пытаюсь поддерживать CORS в моем приложении Node.js, которое использует веб-каркас Express.js.Я прочитал групповое обсуждение Google о том, как с этим справиться, и прочитал несколько статей о том, как работает CORS.Сначала я сделал это (код написан в синтаксисе CoffeeScript):

app.options "*", (req, res) ->
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  # try: 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
  # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

Кажется, он не работает.Похоже, мой браузер (Chrome) не отправляет начальный запрос OPTIONS.Когда я только что обновил блок для ресурса, мне нужно отправить перекрестный запрос GET по адресу:

app.get "/somethingelse", (req, res) ->
  # ...
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

Это работает (в Chrome).Это также работает в Safari.

Я читал, что ...

В браузере, реализующем CORS, каждому перекрестному запросу GET или POST предшествует запрос OPTIONS, который проверяетВ порядке ли GET или POST.

Итак, мой главный вопрос: почему этого не происходит в моем случае?Почему не вызывается мой блок app.options?Зачем мне устанавливать заголовки в моем главном блоке app.get?

Ответы [ 28 ]

635 голосов
/ 07 февраля 2014

Я обнаружил, что проще всего использовать пакет node.js cors .Самое простое использование:

var cors = require('cors')

var app = express()
app.use(cors())

Есть, конечно, много способов настроить поведение в соответствии с вашими потребностями;на странице, указанной выше, приведено несколько примеров.

424 голосов
/ 15 августа 2011

Попробуйте передать управление следующему подходящему маршруту.Если Express сначала совпадает с маршрутом app.get, то он не продолжит маршрут маршрутов, если вы не сделаете это (обратите внимание на использование следующего) :

app.get('somethingelse', function(req, res, next) {
    //..set headers etc.

    next();
});

С точки зрения организацииматериал CORS, я положил его в промежуточное ПО, которое хорошо работает для меня:

//CORS middleware
var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'example.com');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');

    next();
}

//...
app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'cool beans' }));
    app.use(express.methodOverride());
    app.use(allowCrossDomain);
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});
148 голосов
/ 20 декабря 2011

Чтобы ответить на ваш главный вопрос, спецификация CORS требует, чтобы вызов OPTIONS предшествовал POST или GET, если в POST или GET есть непростой контент или заголовки.

Типы контента, для которых требуется предполетный запрос CORS (вызов OPTIONS), это любой тип контента , за исключением следующих :

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

Любые другие типы контента, кроме перечисленных выше, вызовут предполетный запрос.

Что касается заголовков, любой заголовок запроса , кроме следующих , вызовет предполетный запрос:

  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type
  5. DPR
  6. Save-Data
  7. Viewport-Width
  8. Width

Любые другие заголовки запроса активируют предполетный запрос.

Таким образом, вы можете добавить пользовательский заголовок, такой как: x-Trigger: CORS, и это должно вызвать предполетный запрос и попасть в блок OPTIONS.

См. Справочник по MDN Web API - Предварительно просвеченные запросы CORS

110 голосов
/ 24 февраля 2012

Чтобы остаться в той же идее маршрутизации.Я использую этот код:

app.all('/*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

Аналогично http://enable -cors.org / server_expressjs.html пример

78 голосов
/ 21 июля 2016

do

npm install cors --save

и просто добавьте эти строки в ваш основной файл, куда направляется ваш запрос (сохраните его перед любым маршрутом).

const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
49 голосов
/ 31 октября 2012

Я сделал более полное промежуточное ПО, подходящее для экспресс или подключения.Он поддерживает OPTIONS запросы на проверку перед полетом.Обратите внимание, что это разрешит CORS доступ ко всему, вы можете захотеть поставить некоторые проверки, если хотите ограничить доступ.

app.use(function(req, res, next) {
    var oneof = false;
    if(req.headers.origin) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        oneof = true;
    }
    if(req.headers['access-control-request-method']) {
        res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
        oneof = true;
    }
    if(req.headers['access-control-request-headers']) {
        res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
        oneof = true;
    }
    if(oneof) {
        res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
    }

    // intercept OPTIONS method
    if (oneof && req.method == 'OPTIONS') {
        res.send(200);
    }
    else {
        next();
    }
});
35 голосов
/ 15 июня 2016

установить модуль Cors ExpressJS. Вы можете выполнить следующие действия>

Установка

npm install cors

Простое использование (включить все запросы CORS)

var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());

для получения более подробной информации перейдите на https://github.com/expressjs/cors

30 голосов
/ 03 января 2016

Сделайте что-то вроде этого:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});
18 голосов
/ 08 ноября 2014

Тестирование выполнено с использованием экспресс + узла + ионного запуска в разных портах.

Localhost:8100

Localhost:5000

// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests

app.all('*', function(req, res, next) {
       res.header("Access-Control-Allow-Origin", "*");
       res.header("Access-Control-Allow-Headers", "X-Requested-With");
       res.header('Access-Control-Allow-Headers', 'Content-Type');
       next();
});
18 голосов
/ 05 сентября 2017

Сначала просто установите Cors в вашем проекте. Перенесите терминал (командную строку) и cd в каталог вашего проекта и выполните следующую команду:

npm install cors --save

Затем возьмите файл server.js и измените код, добавив в него следующее:

var cors = require('cors');


var app = express();

app.use(cors());

app.use(function(req, res, next) {
   res.header("Access-Control-Allow-Origin", "*");
   res.header('Access-Control-Allow-Methods', 'DELETE, PUT, GET, POST');
   res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
   next();
});

Это сработало для меня ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...