【问题标题】:How to enable cross-origin resource sharing (CORS) in the express.js framework on node.js如何在 node.js 上的 express.js 框架中启用跨域资源共享 (CORS)
【发布时间】:2012-06-26 05:58:12
【问题描述】:

我正在尝试在 node.js 中构建一个支持跨域脚本的 Web 服务器,同时仍提供来自公共目录的静态文件。我正在使用 express.js,但不确定如何允许跨域脚本 (Access-Control-Allow-Origin: *)。

我看到了this post,但没有发现任何帮助。

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 与 app.get。这是 OPTIONS 请求而不是 GET
  • 参见local-web-server 一个简单的节点示例,支持 CORS 的静态网络服务器
  • 查看 enable-cors.org/server_apache.html 了解更多信息
  • "Access-Control-Allow-Origin", "*" 使您的 API 对网络钓鱼应用程序很有吸引力。考虑只允许已知来源。

标签: node.js express cors webserver cross-domain


【解决方案1】:
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 文件中,并根据您的要求更改允许的原始数组。

【讨论】:

    【解决方案2】:

    遵循@Michelle Tilley 解决方案,显然它起初对我不起作用。不知道为什么,也许我正在使用 chrome 和不同版本的节点。在做了一些小的调整之后,它现在对我有用。

    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 与 app.get。这是 OPTIONS 请求而不是 GET
    • 这对我有用(我正在使用 Backbone 获取对象)。我试图弄清楚它是否可以在 IE 8 中工作......似乎应该,但我不知道这个“XDomainRequest”事情是否需要任何特别的东西......developer.mozilla.org/en-US/docs/HTTP/…
    • 为未来用户提供的一些信息:我正在将我的域名重新定向到 Heroku 存储库,这就是我遇到此问题的原因。无论如何,第一个答案在本地有效,但在我将其推送到 heroku 之后无效。然而,这个答案在推送到 heroku 后有效。
    • @KrisHollenbeck 这在 Heroku 上对我不起作用,你还做了什么吗?
    • @BenCraig,不,但在第一次尝试后它实际上停止了对我的工作。所以我实际上仍然有这个问题。
    【解决方案3】:

    如果你想通过“Credentials”使用“cookie”,你必须设置Access-Control-Allow-Credentials: true

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

    【讨论】:

      【解决方案4】:

      试试这个cors npm 模块。

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

      此模块提供了许多功能来微调 cors 设置,例如域白名单、为特定 api 启用 cors 等。

      【讨论】:

        【解决方案5】:

        推荐使用cors express 模块。这允许您将域列入白名单,允许/限制域专门用于路由等,

        【讨论】:

          【解决方案6】:

          查看the example from enable-cors.org:

          在 node.js 上的 ExpressJS 应用中,对路由执行以下操作:

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

          【讨论】:

          • 您好,感谢您的回复。我按照您的建议做了(第一部分,但在请求标头中仍然没有看到任何不同)我在上面附上了我当前的代码。你能解释一下我如何将你的解决方案的其余部分集成到那个吗?
          • 我很惊讶,因为您在 express.static 之前是 useing app.router,它不会修改静态文件的标题;无论如何,我已经更新了我的答案以使其正常工作。
          • 谢谢!我看你是对的。从服务器获取的资产带有请求的标头。我可能还不清楚我的真正问题。我正在尝试使用 get 命令对外部服务器进行 API 调用。这就是我得到错误的地方:XMLHttpRequest 无法加载SOMEURL.com。 Access-Control-Allow-Origin 不允许来源localhost:8888。
          • 我可能误会了。您是否可以控制 SOMEURL.com 上的服务器?
          • 对不起,我现在完全理解你的回答了。非常感谢。感谢您的帮助:)
          【解决方案7】:

          我需要采取的另外一个步骤是将我的 URL 从 http://localhost 切换到 http://127.0.0.0

          【讨论】:

          • 你指的是什么?
          【解决方案8】:

          我用这个:

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

          【讨论】:

            猜你喜欢
            • 2013-01-12
            • 2016-02-06
            • 2016-12-28
            • 2020-12-16
            • 2018-05-04
            • 2016-05-01
            • 2016-04-24
            • 2016-11-26
            • 2012-09-09
            相关资源
            最近更新 更多