Як увімкнути обмін ресурсами між походженнями (CORS) в рамках express.js на node.js


101

Я намагаюся створити веб-сервер у node.js, який підтримуватиме міждоменний сценарій, при цьому надаючи статичні файли із загальнодоступного каталогу. Я використовую express.js і не дуже впевнений, як дозволити сценарій між доменними сценаріями ( Access-Control-Allow-Origin: *).

Я побачив цей пост , який не вважав корисним.

var express = require('express')
  , app = express.createServer();

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

app.configure(function () {
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(app.router);
});

app.configure('development', function () {

    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function () {


    var oneYear = 31557600000;
    //    app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler());
});

app.listen(8888);
console.log('express running at http://localhost:%d', 8888);

Зверніть увагу на app.all vs app.get. ОПЦІЇ запит не отримати
Шимон Додкін

дивіться локальний веб-сервер для прикладу простого вузла, статичного веб-сервера, який підтримує CORS
Lloyd

див. enable-cors.org/server_apache.html для отримання додаткової інформації
Mostafa

"Access-Control-Allow-Origin", "*"робить ваш API цікавим для фішинг-програм. Розглянемо, як дозволити лише відоме походження.
Мартін Шнайдер

Відповіді:


159

Перегляньте приклад з enable-cors.org :

У додатку ExpressJS на node.js виконайте наступні дії зі своїми маршрутами:

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

app.get('/', function(req, res, next) {
  // Handle the get for this route
});

app.post('/', function(req, res, next) {
 // Handle the post for this route
});

Перший дзвінок ( app.all) слід здійснити перед усіма іншими маршрутами у вашій програмі (або принаймні тими, які ви хочете, щоб увімкнено CORS).

[Редагувати]

Якщо ви хочете, щоб заголовки відображалися і для статичних файлів, спробуйте це (переконайтеся, що це перед викликом use(express.static()):

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

Я перевірив це за допомогою вашого коду та отримав заголовки активів із publicкаталогу:

var express = require('express')
  , app = express.createServer();

app.configure(function () {
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "X-Requested-With");
      next();
    });
    app.use(app.router);
});

app.configure('development', function () {
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function () {
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler());
});

app.listen(8888);
console.log('express running at http://localhost:%d', 8888);

Можна, звичайно, функцію упакувати в модуль, щоб ви могли зробити щось на кшталт

// cors.js

module.exports = function() {
  return function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next();
  };
}

// server.js

cors = require('./cors');
app.use(cors());

Гей, дякую за вашу відповідь. Я зробив те, що ви запропонували (перша частина, але все ще не бачу нічого різного в заголовках запиту) Я додав свій поточний код вище. Ви можете пояснити, як я можу інтегрувати решту вашого рішення до цього?
Хлопець

1
Я здивований , що, так як ви useІНГ app.routerдо того, express.staticщо вона не змінює заголовки для статичних файлів; у будь-якому випадку я оновив свою відповідь, щоб вона працювала.
Мішель Тіллі

Дякую! Я бачу, що ти маєш рацію. Активи, отримані від сервера, мають запитувані заголовки. Мені, можливо, не було зрозуміло мого реального питання. Я намагаюся здійснити виклик API на зовнішній сервер із командою get. і ось тут я отримую помилку: XMLHttpRequest не може завантажити SOMEURL.com . Origin localhost: 8888 не заборонено Access-Control-Allow-Origin.
Хлопець

Можливо, я нерозумію. Ви керуєте сервером на SOMEURL.com?
Мішель Тіллі

Вибачте, я зараз повністю розумію вашу відповідь. Дуже дякую. Я ціную вашу допомогу :)
Хлопець

58

Після рішення @Michelle Tilley, мабуть, спочатку це не працювало для мене. Не знаю, чому, можливо, я використовую хром та іншу версію вузла. Після того, як я зробив деякі незначні зміни, вона працює для мене зараз.

app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

Якщо хтось стикається з подібним питанням, як у мене, це може бути корисним.


Зверніть увагу на app.all vs app.get. ОПЦІЇ запит не отримати
Шимон Додкін

Це працює для мене (я виймаю об'єкти за допомогою Backbone). Я намагаюся зрозуміти, чи буде вона працювати в IE 8 ... здається, як слід, але я не знаю, чи потрібно щось особливе для цієї речі "XDomainRequest" ... developer.mozilla.org/en- US / docs / HTTP /…
Адам Люблячий

ДЕЯКНА ІНФОРМАЦІЯ ДЛЯ БУДУЩИХ КОРИСТУВАЧІВ: Я перенаправляю своє доменне ім’я на heroku repo, і саме тому я стикався з цим питанням. У будь-якому випадку, перша відповідь спрацювала локально, але не після того, як я підштовхнула її до героїки. Однак ця відповідь спрацювала після натиску на героїку.
Кріс Холленбек

@KrisHollenbeck Це не працює для мене на heroku, ти щось ще робив?
Бен Крейг

@BenCraig, Ні, але це фактично перестало працювати на мене вже після першої спроби. Тож у мене фактично все ще виникає ця проблема.
Кріс Голленбек

11

Спробуйте цей Корс НПХ модулів.

var cors = require('cors')

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

Цей модуль надає безліч функцій для тонкої настройки параметрів корів, таких як список домену, включення корів для конкретних apis тощо.


2

Я використовую це:

var app = express();

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

h.readFiles('controllers').forEach(function(file){
  require('./controllers/' + file)(app);
})
;

app.listen(port);
console.log('server listening on port ' + port);

цей код передбачає, що ваші контролери розташовані в каталозі контролерів. кожен файл у цьому каталозі має бути приблизно таким:

module.exports = function(app){

    app.get('/', function(req, res, next){
        res.end('hi');
    });

}

1

Рекомендується використовувати в CORS експрес модуль. Це дозволяє дозволити білі домени, дозволити / обмежити домени спеціально до маршрутів тощо,


0

Ви повинні встановити Access-Control-Allow-Credentials: true, якщо ви хочете використовувати "cookie" через "Повноваження"

app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

0
app.use(function(req, res, next) {
var allowedOrigins = [
  "http://localhost:4200"
];
var origin = req.headers.origin;
console.log(origin)
console.log(allowedOrigins.indexOf(origin) > -1)
// Website you wish to allow to
if (allowedOrigins.indexOf(origin) > -1) {
  res.setHeader("Access-Control-Allow-Origin", origin);
}

// res.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");

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

});

Додайте цей код у файл index.js або server.js та змініть дозволений масив початків відповідно до ваших вимог.


-6

Ще одним кроком, який мені потрібно було зробити, було переключення моєї URL-адреси http://localhostнаhttp://127.0.0.0


На що ви маєте на увазі?
Blunderfest
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.