如何在 node.js 的 Express.js 框架中启用跨来源资源共享(CORS)

我试图在 node.js 中构建一个 Web 服务器,它将支持跨域脚本,同时仍然提供来自公共目录的静态文件。我正在使用 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);
168906 次浏览

Check out the example from enable-cors.org:

In your ExpressJS app on node.js, do the following with your routes:

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

The first call (app.all) should be made before all the other routes in your app (or at least the ones you want to be CORS enabled).

[Edit]

If you want the headers to show up for static files as well, try this (make sure it's before the call to 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();
});

I tested this with your code, and got the headers on assets from the public directory:

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

You could, of course, package the function up into a module so you can do something like

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

Following @Michelle Tilley solution, apparently it didn't work for me at first. Not sure why, maybe I am using chrome and different version of node. After did some minor tweaks, it is working for me now.

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

In case someone facing similar issue as mine, this might be helpful.

I use this:

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

this code assumes that your controllers are located in the controllers directory. each file in this directory should be something like this:

module.exports = function(app){


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


}

One additional step I needed to take was to switch my URL from http://localhost to http://127.0.0.0

Recommend using the cors express module. This allows you to whitelist domains, allow/restrict domains specifically to routes, etc.,

Try to this cors npm modules.

var cors = require('cors')


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

This module provides many features to fine tune cors setting such as domain whitelisting, enabling cors for specific apis etc.

You must set Access-Control-Allow-Credentials: true, if you want to use "cookie" via "Credentials"

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

});

Add this code in your index.js or server.js file and change the allowed origin array according to your requirement.