Почему добавление заголовков 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 ]

9 голосов
/ 24 августа 2015

Это работает для меня, так как это простая реализация внутри маршрутов, я использую Meanjs и работаю нормально, Safari, Chrome и т. Д.

app.route('/footer-contact-form').post(emailer.sendFooterMail).options(function(req,res,next){ 
        res.header('Access-Control-Allow-Origin', '*'); 
        res.header('Access-Control-Allow-Methods', 'GET, POST');
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
        return res.send(200);

    });
9 голосов
/ 24 января 2017

Некоторое время назад я столкнулся с этой проблемой, поэтому я сделал это, чтобы разрешить CORS в моем приложении nodejs:

Сначала вам необходимо установить cors с помощью следующей команды:

npm install cors --save

Теперь добавьте следующий код в файл запуска вашего приложения, например (app.js or server.js)

var express = require('express');
var app = express();

var cors = require('cors');
var bodyParser = require('body-parser');

//enables cors
app.use(cors({
  'allowedHeaders': ['sessionId', 'Content-Type'],
  'exposedHeaders': ['sessionId'],
  'origin': '*',
  'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
  'preflightContinue': false
}));

require('./router/index')(app);
6 голосов
/ 06 января 2018

Если вы хотите настроить контроллер, вы можете использовать:

res.setHeader('X-Frame-Options', 'ALLOWALL');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

Обратите внимание, что это также разрешит использование фреймов.

3 голосов
/ 25 сентября 2018

См. Код ниже для того же.Источник: Academind / node-restful-api

const express = require('express');
const app = express();

//acts as a middleware
//to handle CORS Errors
app.use((req, res, next) => { //doesn't send response just adjusts it
    res.header("Access-Control-Allow-Origin", "*") //* to give access to any origin
    res.header(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization" //to give access to all the headers provided
    );
    if(req.method === 'OPTIONS'){
        res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET'); //to give access to all the methods provided
        return res.status(200).json({});
    }
    next(); //so that other routes can take over
})
3 голосов
/ 06 мая 2014

Моим самым простым решением с Express 4.2.0 (EDIT: в 4.3.0, похоже, не работает) было:

function supportCrossOriginScript(req, res, next) {
    res.status(200);
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Content-Type");

    // res.header("Access-Control-Allow-Headers", "Origin");
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // res.header("Access-Control-Allow-Methods","POST, OPTIONS");
    // res.header("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE, PUT, HEAD");
    // res.header("Access-Control-Max-Age","1728000");
    next();
}

// Support CORS
app.options('/result', supportCrossOriginScript);

app.post('/result', supportCrossOriginScript, function(req, res) {
    res.send('received');
    // do stuff with req
});

Я полагаю, что выполнение app.all('/result', ...) тоже будет работать ...

2 голосов
/ 17 июня 2019

По моему index.js я добавил:

app.use((req, res, next) => {
   res.header("Access-Control-Allow-Origin", "*");
   res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
   res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
   next();
}) 
2 голосов
/ 29 августа 2018

Использование Express Middleware прекрасно работает для меня.Если вы уже используете Express, просто добавьте следующие правила промежуточного программного обеспечения.Это должно начать работать.

app.all("/api/*", function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
  res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
  return next();
});

app.all("/api/*", function(req, res, next) {
  if (req.method.toLowerCase() !== "options") {
    return next();
  }
  return res.send(204);
});

Ссылка

2 голосов
/ 25 марта 2016

В дополнение к тому, что сказали другие, не забывайте, что если вы не используете nodemon, вам потребуется перезапустить сервер узлов, чтобы изменения вступили в силу!

Я лично по привычке обновлял свой браузер, забывая, что это код на стороне сервера.

1 голос
/ 15 марта 2019

Ниже работало для меня, надеюсь, это кому-нибудь поможет!

const express = require('express');
const cors = require('cors');
let app = express();

app.use(cors({ origin: true }));

Получил ссылку от https://expressjs.com/en/resources/middleware/cors.html#configuring-cors

1 голос
/ 17 января 2019

Это похоже на ответ Пэта с той разницей, что я заканчиваю с res.sendStatus (200);вместо следующего ();

Код будет перехватывать все запросы типа метода OPTIONS и отправлять обратно заголовки контроля доступа.

app.options('/*', (req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
    res.sendStatus(200);
});

Код принимает CORS из всех источников, как было запрошено в вопросе.Тем не менее, было бы лучше заменить * конкретным источником, то есть http://localhost:8080, чтобы предотвратить неправильное использование.

Поскольку мы используем метод app.options вместо метода app.use, который мы используемне нужно делать эту проверку:

req.method === 'OPTIONS'

, которую мы можем видеть в некоторых других ответах.

Я нашел ответ здесь: http://johnzhang.io/options-request-in-express.

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