为nodejs中的多个域启用Access-Control-Allow-Origin

时间:2014-07-22 21:03:53

标签: node.js cors

我正在尝试在node.js中允许CORS,但问题是如果设置了*,我就无法将Access-Control-Allow-Origin设置为Access-Control-Allow-Credentials

该规范也说我不能为Access-Control-Allow-Origin做一个数组或逗号分隔值,建议的方法是做类似于Access-Control-Allow-Origin Multiple Origin Domains?

的操作

但我似乎无法在node.js

中这样做
["http://mydomain.com:9001", "http://mydomain.com:5001"].map(function(domain) {
  res.setHeader( "Access-Control-Allow-Origin", domain );
});
res.header( "Access-Control-Allow-Credentials", true );

这里的问题是它被数组中的最后一个值覆盖,因此标题将设置为res.setHeader( "Access-Control-Allow-Origin", "http://mydomain.com:5001" );

客户端浏览器出错:

  

XMLHttpRequest无法加载http://mydomain.com:9090/api/sync。该   'Access-Control-Allow-Origin'标头有一个值   'http://mydomain.com:5001'不等于提供的原点。   因此,不允许原点“http://mydomain.com:9001”访问。

4 个答案:

答案 0 :(得分:139)

以下是我在快递申请中使用的允许多个来源的内容

app.use(function(req, res, next) {
  var allowedOrigins = ['http://127.0.0.1:8020', 'http://localhost:8020', 'http://127.0.0.1:9000', 'http://localhost:9000'];
  var origin = req.headers.origin;
  if(allowedOrigins.indexOf(origin) > -1){
       res.setHeader('Access-Control-Allow-Origin', origin);
  }
  //res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:8020');
  res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Allow-Credentials', true);
  return next();
});

答案 1 :(得分:9)

不确定这是否迟到但我通过设置解决了它: res.setHeader(" Access-Control-Allow-Origin",req.headers.origin);

这将只允许每个连接,因为headers.origin将随每个查询一起发送。 由于我一般都是Node.js和web noob,所以我很感激对此答案的任何评论。此外,这可能会破坏目的,限制起源接受,并且在生产中使用可能很糟糕。

您可能希望编写一个函数来检查req.headers.origin是否为白名单域(来自硬编码数组),如果数组中存在该域,则只返回该域。

答案 2 :(得分:6)

检查您的白名单与您的req.headers.origin例如

var origins = ['a.com', 'b.com', 'c.com', 'boobies.com'];
for(var i=0;i<origins.length;i++){
    var origin = origins[i];
    if(req.headers.origin.indexOf(origin) > -1){ 
         res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
         return;
    }
    // else, tough cookies. 
}

享受。

答案 3 :(得分:6)

这是一个简单的中间件函数,用于从白名单中提供正确的CORS头。将其设置在快递应用程序的顶部附近将允许您的所有路由在提供内容之前从白名单中设置正确的标题。

app.use(function(req, res, next){
  var whitelist = ['localhost:4000', 'localhost:3000', 'anydomain.com']
  var host = req.get('host');

  whitelist.forEach(function(val, key){
    if (host.indexOf(val) > -1){
      res.setHeader('Access-Control-Allow-Origin', host);
    }
  })

  next();
});