【问题标题】:Nginx Config for Cors - add_header directive is not allowed用于 Cors 的 Nginx 配置 - 不允许使用 add_header 指令
【发布时间】:2021-04-27 19:36:44
【问题描述】:

我正在尝试将 CORS 指令添加到我的 nginx 文件中,以作为简单的静态 HTML 站点。 (取自这里http://enable-cors.org/server_nginx.html

会不会有理由抱怨第一个 add_header 指令说“这里不允许使用 add_header”指令?

我的配置文件示例

server {
    if ($http_origin ~* (https?://[^/]*\.domain\.com(:[0-9]+)?)$) {
        set $cors "true";
    }

    if ($request_method = 'OPTIONS') {
        set $cors "${cors}options";
    }

    if ($request_method = 'GET') {
        set $cors "${cors}get";
    }
    if ($request_method = 'POST') {
        set $cors "${cors}post";
    }

    if ($cors = "trueget") {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Credentials' 'true';
    }

    if ($cors = "truepost") {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Credentials' 'true';
    }

    if ($cors = "trueoptions") {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        return 204;
    }

    listen 8080;

    location / {
        root /var/www/vhosts/mysite;
    }
}

【问题讨论】:

    标签: nginx


    【解决方案1】:

    add_header 必须放在 httpserverlocationif in location 块下。

    您在if in server 下放置。将它们移到location 块下。

    server {
    
    
        listen 8080;
    
        location / {
            root /var/www/vhosts/mysite;
    
            if ($http_origin ~* (https?://[^/]*\.domain\.com(:[0-9]+)?)$) {
                set $cors "true";
            }
    
            if ($request_method = 'OPTIONS') {
                set $cors "${cors}options";
            }
    
            if ($request_method = 'GET') {
                set $cors "${cors}get";
            }
            if ($request_method = 'POST') {
                set $cors "${cors}post";
            }
    
            if ($cors = "trueget") {
                add_header 'Access-Control-Allow-Origin' "$http_origin";
                add_header 'Access-Control-Allow-Credentials' 'true';
            }
    
            if ($cors = "truepost") {
                add_header 'Access-Control-Allow-Origin' "$http_origin";
                add_header 'Access-Control-Allow-Credentials' 'true';
            }
    
            if ($cors = "trueoptions") {
                add_header 'Access-Control-Allow-Origin' "$http_origin";
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
                add_header 'Content-Length' 0;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                return 204;
            }
        }
    }
    

    来源:http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header

    【讨论】:

    【解决方案2】:

    规则 if in location 可以通过一些技巧绕过,这样您就不必在每个 location 块中编写/包含 CORS 规则。

    server {
        set $cors_origin "";
        set $cors_cred   "";
        set $cors_header "";
        set $cors_method "";
    
        if ($http_origin ~* "^http.*\.yourhost\.com$") {
                set $cors_origin $http_origin;
                set $cors_cred   true;
                set $cors_header $http_access_control_request_headers;
                set $cors_method $http_access_control_request_method;
        }
    
        add_header Access-Control-Allow-Origin      $cors_origin;
        add_header Access-Control-Allow-Credentials $cors_cred;
        add_header Access-Control-Allow-Headers     $cors_header;
        add_header Access-Control-Allow-Methods     $cors_method;
    }
    

    这是可行的,因为如果它的值为空字符串,nginx 将不会返回标头。

    【讨论】:

    • 这确实有效。应该得到更多的信任。 add_header 实际上很挑剔,它允许add_header X-Content-Type-Options nosniff; 在位置块之外,但是当它是Access-control-* 时会报错。旧版本的 nginx 也接受这些。
    • 但是你还在使用if in server。
    • @MohitSingh 这正是如何在服务器块中使用if 的答案!如果使用 if in location,您必须为所有需要 CORS 标头的 location 块编写/包含相同的规则。此外,除非您完全了解If is Evil,否则不建议使用if in location
    【解决方案3】:

    首先,让我说,在浏览了网络之后,我发现到处都是这个答案:

    location ~* \.(eot|ttf|woff|woff2)$ { add_header Access-Control-Allow-Origin *; }

    但是,我决定用一个单独的答案来回答这个问题,因为我在花了大约十多个小时寻找解决方案后才设法让这个特定的解决方案工作。

    Nginx 似乎默认没有定义任何 [正确] 字体 MIME 类型。通过关注this tuorial,我发现我可以添加以下内容:

    application/x-font-ttf           ttc ttf;
    application/x-font-otf           otf;
    application/font-woff            woff;
    application/font-woff2           woff2;
    application/vnd.ms-fontobject    eot;
    

    到我的etc/nginx/mime.types 文件。

    如上所述,上述解决方案随后奏效。显然,此答案旨在共享字体,但绝对值得检查一下 MIME 类型是否为您正在努力使用的任何其他资源定义(正确)。

    【讨论】:

      猜你喜欢
      • 2019-03-26
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 2021-08-06
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      相关资源
      最近更新 更多