nginx 配置以启用具有源匹配的 CORS

Sla*_* II 8 nginx cross-domain cors preflight

我尝试为 nginx使用一个非常流行的配置,它启用 CORS 并支持使用正则表达式进行源匹配。

这是我的配置:

server {
    listen 80 default_server;
    root /var/www;

    location / {
        if ($http_origin ~ '^http://(www\.)?example.com$') {
            add_header Access-Control-Allow-Origin "$http_origin";
        }

        # Handling preflight requests
        if ($request_method = OPTIONS) {
            add_header Content-Type text/plain;
            add_header Content-Length 0;
            return 204;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,此配置必须使用两个条件:一个是匹配原始域名,另一个是捕获预检请求。因此,当第二个条件匹配时,第一个条件的标头不会添加到响应中。

根据If Is Evil官方文章,这是 nginx 的预期行为。

如果If Is Evil我如何在 nginx 中启用 CORS 呢?或者也许有办法以某种方式克服这种限制?

Iva*_*sky 14

您可以尝试使用mapi 而不是第一个if块:

map $http_origin $allow_origin {
    ~^http://(www\.)?example.com$ $http_origin;
}
map $http_origin $allow_methods {
    ~^http://(www\.)?example.com$ "OPTIONS, HEAD, GET";
}

server {
    listen 80 default_server;
    root /var/www;

    location / {
        add_header Access-Control-Allow-Origin $allow_origin;
        add_header Access-Control-Allow-Methods $allow_methods;

        # Handling preflight requests
        if ($request_method = OPTIONS) {
            add_header Content-Type text/plain;
            add_header Content-Length 0;
            return 204;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

nginx 将拒绝添加空的 HTTP 标头,因此只有Origin在请求中存在标头并且与此正则表达式匹配时才会添加它们。