我试图在使用Express.js web框架的Node.js应用程序中支持CORS。我已经阅读了谷歌关于如何处理这个问题的小组讨论,并阅读了一些关于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)没有发送最初的选项请求。当我刚刚更新了块的资源,我需要提交一个跨起源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块设置标题?


当前回答

使用CORS包。然后输入这些参数:

cors({credentials: true, origin: true, exposedHeaders: '*'})

其他回答

下面的代码将工作,但首先安装cors通过:

NPM安装——保存cors

然后:

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

我们可以避免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");
});

尝试将控制权传递给下一个匹配的路由。如果Express首先匹配app.get路由,那么它不会继续到options路由,除非你这样做(注意使用next):

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

安装expressjs的cors模块。你可以按照这些步骤来做

安装

npm install cors

简单使用(启用所有CORS请求)

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

欲了解更多详情,请访问https://github.com/expressjs/cors

我发现用npm request包(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'));
});