【问题标题】:How to allow access via CORS to multiple domains within nginx如何允许通过 CORS 访问 nginx 中的多个域
【发布时间】:2016-08-03 14:13:43
【问题描述】:

如果您查看的是 website.com 而不是 www.website.com,我在将 SVG 加载到我的网站时遇到了一些问题。该网站在 nginx 服务器上,所以我添加了这个,它解决了这个问题:

location / {
  add_header Access-Control-Allow-Origin "*"; 
}

但是,根据我所阅读的内容,这似乎会导致安全问题?有没有办法只指定 www.website.com 和 website.com 而不是 *?我问是因为我在 PHP 中遇到了这个问题,这似乎是我需要的,但对于 nginx:

header('Access-Control-Allow-Origin: http://www.website.com');
header('Access-Control-Allow-Origin: http://website.com');

【问题讨论】:

标签: nginx cors


【解决方案1】:

Access-Control-Allow-Origin 上的 W3 spec 解释说,可以通过空格分隔的列表指定多个来源。但在实践中,浏览器中的当前实现不太可能正确解释这一点(例如,在撰写本文时,Firefox 45 失败);由this comment总结。

为了实现你所需要的,那么下面的 nginx sn-p 会检查传入的Origin 标头并相应地调整响应:

location / {
    if ($http_origin ~* "^https?://(website.com|www.website.com)$") {
        add_header Access-Control-Allow-Origin "$http_origin";
    }
}

根据需要在正则表达式中添加更多域;如果您想单独支持http://,可以删除s?

请注意,如果您通过 HTML(例如 <img src="http://example.com/img.svg>)在网页上直接包含 SVG,则不需要 CORS 和 Access-Control-Allow-Origin。如果你为你的图片使用crossorigin属性(比如CORS Enabled Images),或者通过JS等加载,那么以上是需要的。


在 nginx 中添加多个同名标头的原始答案(CORS 引用已删除,因为它们不正确):

您可以在给定块中多次使用add_header

location / {
  add_header Header-Name "value"; 
  add_header Header-Name "value2"; 
}

您的回复将包含:

Header-Name: value
Header-Name: value2

add_header 还可以包含变量,请注意,如果您希望将标头添加到所有响应代码(包括错误)中,您可能需要添加 always 参数(请参阅http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header)。

【讨论】:

  • 执行此操作时出现此错误:XMLHttpRequest cannot load http://www.website.com/image.svg. The 'Access-Control-Allow-Origin' header contains multiple values 'http://www.website.com, http://website.com', but only one is allowed. Origin 'http://website.com' is therefore not allowed access.
  • @Shonna 调整了答案,因为目标不是使用多个标头,因为 CORS 仅使用一个标头。
【解决方案2】:

这是一个使用map的解决方案。

此设置允许您向 my-domain.com 上的任何子域和任何端口发出请求。

map $http_origin $allow_origin {
    ~^https?://(.*\.)?my-domain.com(:\d+)?$ $http_origin;
    # NGINX won't set empty string headers, so if no match, header is unset.
    default "";
}

server {
    listen 80 default_server;
    server_name _;
    add_header 'Access-Control-Allow-Origin' $allow_origin;
    # ...
}

http://nginx.org/en/docs/http/ngx_http_map_module.html

在 NGINX 的位置块中使用 if 时会发生一些意想不到的事情。不建议这样做。 https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/https://agentzh.blogspot.com/2011/03/how-nginx-location-if-works.html

【讨论】:

  • 谢谢,他帮了我大忙,因为 if 有一些意想不到的副作用。
  • 这看起来很有希望,但我无法让它工作。好像没有效果。
  • origin 不是默认的 http 标头,浏览器不会发送它。您可能想使用 http_host 并编辑正则表达式以不包含协议 (http://)
  • 这是我认为的最佳答案。干净利落。谢谢,@eric-ihli
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 2019-07-01
相关资源
最近更新 更多