Как разрешить CORS?

Я пытаюсь поддерживать 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?

577
15 авг. '11 в 19:53
источник поделиться
27 ответов

Чтобы ответить на ваш главный вопрос, спецификация 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.

139
20 дек. '11 в 11:32
источник

Связанные вопросы


Похожие вопросы

Я нашел самый простой способ использовать пакет node.js cors. Простейшее использование:

var cors = require('cors')

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

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

621
07 февр. '14 в 11:16
источник

Попробуйте передать управление следующему соответствующему маршруту. Если 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'));
});
425
15 авг. '11 в 22:45
источник

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

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 example

110
24 февр. '12 в 13:46
источник

делать

npm install cors --save

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

const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
75
21 июля '16 в 12:26
источник

Я сделал более полное промежуточное программное обеспечение, подходящее для экспресс-связи или подключения. Он поддерживает запросы 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();
    }
});
49
31 окт. '12 в 0:49
источник

установить 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

36
15 июня '16 в 23:37
источник

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

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();
});
31
03 янв. '16 в 11:24
источник

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

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();
});
19
08 нояб. '14 в 23:35
источник

сначала просто установите корс в свой проект. Возьмите терминал (командная строка) и 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();
});

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

19
05 сент. '17 в 12:08
источник

Это работает для меня, поскольку это легкая реализация внутри маршрутов, im с использованием meanjs и его работоспособного режима, сафари, хром и т.д.

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);

    });
10
24 авг. '15 в 23:13
источник

Некоторое время назад я столкнулся с этой проблемой, поэтому я сделал это, чтобы разрешить 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);
10
24 янв. '17 в 13:19
источник

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

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');

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

7
06 янв. '18 в 1:01
источник

Можете сослаться на код ниже для того же. Источник: 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
})
4
25 сент. '18 в 15:29
источник

Использование 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);
});

Справка

3
29 авг. '18 в 21:29
источник

Мое самое простое решение с 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', ...) тоже будет работать...

3
06 мая '14 в 2:47
источник

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

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

3
25 марта '16 в 15:51
источник

Мне было очень легко сделать это с пакетом запросов npm (https://www.npmjs.com/package/request)

Затем я основал свое решение на этом посту http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/

'use strict'

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

let proxyConfig = {
    url : {
        base: 'http://servertoreach.com?id=',
    }
}

/* setting up and configuring node express server for the application */
let server = express();
server.set('port', 3000);


/* methods forwarded to the servertoreach proxy  */
server.use('/somethingElse', function(req, res)
{
    let url = proxyConfig.url.base + req.query.id;
    req.pipe(request(url)).pipe(res);
});


/* start the server */
server.listen(server.get('port'), function() {
    console.log('express server with a proxy listening on port ' + server.get('port'));
});
2
10 февр. '16 в 16:06
источник

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

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

2
15 марта '19 в 12:02
источник

Это похоже на ответ Пэта с той разницей, что я заканчиваю с 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.

2
17 янв. '19 в 13:39
источник

Мы можем избежать CORS и перенаправлять запросы на другой сервер:

// config:
var public_folder = __dirname + '/public'
var apiServerHost = 'http://other.server'

// code:
console.log("starting server...");

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

// serve static files
app.use(express.static(public_folder));

// if not found, serve from another server
app.use(function(req, res) {
    var url = apiServerHost + req.url;
    req.pipe(request(url)).pipe(res);
});

app.listen(80, function(){
    console.log("server ready");
});
1
15 мая '16 в 11:45
источник

Я использовал следующие шаги для своего веб-приложения, и у меня был успех:

Добавьте пакет cors в экспресс:

npm install cors --save

Добавьте следующие строки после конфигурации bodyParser. У меня были некоторые неприятности, добавленные перед bodyParser:

 // enable cors to the server
const corsOpt = {
    origin: process.env.CORS_ALLOW_ORIGIN || '*', // this work well to configure origin url in the server
    methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'], // to works well with web app, OPTIONS is required
    allowedHeaders: ['Content-Type', 'Authorization'] // allow json and token in the headers
};
app.use(cors(corsOpt)); // cors for all the routes of the application
app.options('*', cors(corsOpt)); // automatic cors gen for HTTP verbs in all routes, This can be redundant but I kept to be sure that will always work.
1
14 июня '18 в 16:36
источник

используя nodejs без экспресс/внешних библиотек Я использовал метод ниже в моем файле server.js. Ключевыми частями здесь является получение источника из заголовка запроса, а затем разрешение его в ответе сервера, после чего мы можем установить заголовок, который будет возвращен, включая разрешенный источник, если совпадение найдено.

    **const origin = req.headers.origin;**

      let decoder = new StringDecoder('utf-8');
      let buffer = '';
      req.on('data', function (data) {
        buffer += decoder.write(data);
      });
      req.on('end', function () {
        buffer += decoder.end();

        let chosenHandler = typeof (server.router[trimmedPath]) !== 'undefined' ? server.router[trimmedPath] : handlers.notFound;

const data = { ....data object vars}

// should be wrapped in try catch block
      chosenHandler(data, function (statusCode, payload, contentType) {
        server.processHandlerResponse(res, method, trimmedPath, statusCode, payload, contentType, **origin**);


server.processHandlerResponse = function (res, method, trimmedPath, statusCode, payload, contentType, origin) {
  contentType = typeof (contentType) == 'string' ? contentType : 'json';

  statusCode = typeof (statusCode) == 'number' ? statusCode : 200;

  let payloadString = '';
  if (contentType == 'json') {
    res.setHeader('Content-Type', 'application/json');

    const allowedOrigins = ['https://www.domain1.com', 'https://someotherdomain','https://yetanotherdomain',
    ...// as many as you need
  ];
    **if (allowedOrigins.indexOf(origin) > -1) {
        res.setHeader('Access-Control-Allow-Origin', origin);
    }**
    payload = typeof (payload) == 'object' ? payload : {};
    payloadString = JSON.stringify(payload);
  }

... //  if (other content type) ...rinse and repeat..
0
02 марта '19 в 10:40
источник
const express = require("express");
const router = express.Router();
const app = express();
const cors = require("cors"); 



const options = {
  origin: true,
  "Access-Control-Allow-Credentials": true,

  "Access-Control-Allow-Origin": true,
  "Access-Control-Allow-Headers": true,
  "Access-Control-Expose-Headers": true
};


app.use(cors(options));
router.get("/", cors(options), (req, res) => {
  res.render("index", { title: "Express" });
});

module.exports = router;

Для GOOGLE CHROME необходимо добавить расширение "Allow-Control-Allow-Origin"

Заголовок Access-Control-Allow-Origin (заголовок ответа) указывает, можно ли разделить ресурс на основе возврата значения заголовка запроса источника. Заголовок Access-Control-Allow-Origin открывает дверь для перекрестного доступа

Access-Control-Allow-Credentials (заголовок ответа): true используется, чтобы указать, что клиенту разрешено использовать учетные данные. По умолчанию ответы на запросы с учетными данными не могут быть прочитаны клиентским скриптом. Таким образом, вы можете получить доступ к ответу. Кроме того, по умолчанию CORS не включает файлы cookie в запросах с несколькими источниками, и это может привести к классу уязвимостей, который называется подделкой запросов между сайтами или CSRF. Чтобы снизить вероятность появления уязвимостей CSRF в CORS, CORS требует, чтобы и сервер, и клиент подтвердили, что файлы cookie можно включать в запросы.

Access-Control-Expose-Headers (заголовок ответа) указывает, какие заголовки безопасны для показа. Список заголовков ответа можно прочитать. По умолчанию отображаются только 6 простых заголовков ответов: Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma.

Access-Control-Request-Headers (заголовок запроса) указывает, какие заголовки HTTP можно использовать во время фактического запроса.

origin = true (заголовок запроса) отражает происхождение запроса. Если это неверно, Cors будет отключен.

0
20 мая '19 в 8:22
источник

В машинописном тексте, если вы хотите использовать пакет node.js cors

/**
* app.ts
* If you use the cors library
*/

import * as express from "express";
[...]
import * as cors from 'cors';

class App {
   public express: express.Application;

   constructor() {
       this.express = express();
       [..]
       this.handleCORSErrors();
   }

   private handleCORSErrors(): any {
       const corsOptions: cors.CorsOptions = {
           origin: 'http://example.com',
           optionsSuccessStatus: 200
       };
       this.express.use(cors(corsOptions));
   }
}

export default new App().express;

Если вы не хотите использовать библиотеки сторонних компонентов для обработки ошибок cors, вам необходимо изменить метод handleCORSErrors().

/**
* app.ts
* If you do not use the cors library
*/

import * as express from "express";
[...]

class App {
   public express: express.Application;

   constructor() {
       this.express = express();
       [..]
       this.handleCORSErrors();
   }

   private handleCORSErrors(): any {
       this.express.use((req, res, next) => {
           res.header("Access-Control-Allow-Origin", "*");
           res.header(
               "Access-Control-ALlow-Headers",
               "Origin, X-Requested-With, Content-Type, Accept, Authorization"
           );
           if (req.method === "OPTIONS") {
               res.header(
                   "Access-Control-Allow-Methods",
                   "PUT, POST, PATCH, GET, DELETE"
               );
               return res.status(200).json({});
           } 
           next(); // send the request to the next middleware
       });
    }
}

export default new App().express;

Для использования файла app.ts

/**
* server.ts
*/
import * as http from "http";
import app from "./app";

const server: http.Server = http.createServer(app);

const PORT: any = process.env.PORT || 3000;
server.listen(PORT);
0
09 июля '18 в 12:41
источник

Самый простой подход - установить модуль Cors в ваш проект, используя:

npm i --save cors

Затем в файл вашего сервера импортируйте его, используя следующее:

import cors from 'cors';

Затем просто используйте его в качестве промежуточного ПО, например:

app.use(cors());

Надеюсь это поможет!

0
20 апр. '19 в 6:53
источник

Ниже приведен код, но сначала установите cors:

npm установить --save корс

Затем:

module.exports = function(app) { 
var express = require("express");
var cors = require('cors');
var router = express.Router();
app.use(cors());

app.post("/movies",cors(), function(req, res) { 
res.send("test");
});
0
02 окт. '18 в 16:40
источник

Посмотрите другие вопросы по меткам или Задайте вопрос