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

Ali*_*Ali 62 node.js cors

我试图让在node.js的CORS但问题是,我不能设置*Access-Control-Allow-Origin,如果Access-Control-Allow-Credentials设置.

另外规范说我不能做一个数组或逗号分隔值,Access-Control-Allow-Origin建议的方法是做类似于这个Access-Control-Allow-Origin多个原始域的东西?

但我似乎无法在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 );
Run Code Online (Sandbox Code Playgroud)

这里的问题是它被数组中的最后一个值覆盖,因此标题将被设置为 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 "访问.

Cha*_*dru 158

以下是我在快递应用程序中使用的允许多个来源的内容

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();
});
Run Code Online (Sandbox Code Playgroud)

  • res.header和res.setHeader之间有区别吗? (6认同)
  • @pro.mean 此处的“return next()”将确保“app.use”将返回“next”回调返回的任何内容。只是“next()”仍然会调用回调,但不会向“app.use”的调用者提供回调的返回值。你无法知道是否有必要,除非你知道什么在栈下调用“app.use”,以及栈上的“next”处理函数是什么。 (2认同)

Mat*_*att 10

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

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

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

  • 这是一种过于复杂的方式来说res.setHeader("Access-Control-Allow-Origin","*"); (11认同)
  • @AlexanderGonchiy不,不是.事实上它是完全不同的,接受所有东西与动态设置为单一来源.以凭证为例.如果你想允许凭证,那么你的`Access-Control-Allow-Origin`不能使用`*`,但它仍然适用于这个解决方案.谢谢你的帖子 (10认同)
  • 对遇到这个答案的人的警告;这几乎总是一个严重的安全漏洞。最好的情况下它与 Access-Control-Allow-Origin: * 相同。如果使用其他 CORS 标头,这可能会导致严重的跨站点请求伪造漏洞。漏洞跟踪数据库(例如 CVE)有大量与此答案建议的漏洞完全匹配的漏洞。 (4认同)

Ros*_*oss 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. 
}
Run Code Online (Sandbox Code Playgroud)

请享用.


Ala*_* L. 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();
});
Run Code Online (Sandbox Code Playgroud)

  • 不确定自 2015 年以来情况是否发生了变化,但是当我检查 `req` 时,`req.get('host')` 的值是服务器本身的 URL。如果请求来自服务器外部,这就是我们需要白名单的原因,`req.get('origin')` 或 `req.get('referrer')` 存储发出请求的 URL。我在两者之间看到的唯一区别是 `referrer` 包含一个尾部斜杠。 (2认同)