如何根据请求中的Origin头正确设置nginx Access-Control-Allow-Origin到响应头?

sor*_*rin 22 javascript nginx cors

我正在寻找一个nginx配置设置,它确实设置了Access-Control-Allow-Origin收到的值Origin.

似乎该*方法不适用于Chrome,并且多个URL不适用于Firefox,因为CORS规范不允许这样做.

到目前为止,唯一的解决方案是设置Access-Control-Allow-Origin原始接收的值(是的,可以实现一些验证).

问题是如何在nginx中执行此操作,最好不要安装其他扩展.

set $allow_origin "https://example.com"
# instead I want to get the value from Origin request header
add_header 'Access-Control-Allow-Origin' $allow_origin;
Run Code Online (Sandbox Code Playgroud)

phy*_*lae 41

使用if有时会打破其他配置,如try_files.您最终可能会遇到意外的404.

请改用地图

map $http_origin $cors_header {
    default "";
    "~^https?://[^/]+\.example\.com(:[0-9]+)?$" "$http_origin";
}

server {
    ...
    location / {
        add_header Access-Control-Allow-Origin $cors_header;
        try_files $uri $uri/ /index.php;
    }
    ...
 }
Run Code Online (Sandbox Code Playgroud)

如果是邪恶的


Mne*_*quo 19

我自己开始使用它,这是我当前Nginx配置中的一行:

add_header 'Access-Control-Allow-Origin' "$http_origin";
Run Code Online (Sandbox Code Playgroud)

这将设置标头以允许请求的来源作为唯一允许的来源.所以你来自哪里是唯一允许的地方.所以它与允许"*"不应该有太大的不同,但从浏览器的角度看它看起来更具体.

此外,您可以在Nginx配置中使用条件逻辑来指定允许的主机名白名单.以下是https://gist.github.com/Ry4an/6195025的示例

if ($http_origin ~* (whitelist\.address\.one|whitelist\.address\.two)$) {
  add_header Access-Control-Allow-Origin "$http_origin";
}
Run Code Online (Sandbox Code Playgroud)

我打算在我自己的服务器上尝试这种技术,将允许的域列入白名单.

  • 如果在多个主机上有需要访问CORS资源的页面,则在不使用*的情况下会遇到问题。通过指定来源,您可以将缓存中的资源锁定到请求它的第一页。以后来自其他页面的请求将命中该缓存页面,该页面允许错误的来源。即使您的白名单允许它们,它们也将无法加载。http://stackoverflow.com/questions/21104810/what-c​​ould-explain-the-browser-intermittently-not-loading-some-cors-crossorigin?noredirect=1&lq=1 (2认同)
  • @Mnebuerquo缓存问题可以通过在$ cache_key中添加$ http_origin来解决。发送`Vary:Origin`头应该负责客户端缓存。(IE / EDGE似乎与Vary标头有关) (2认同)