Nginx Config for Cors - add_header directive is no

2019-03-18 01:58发布

问题:

I am trying add CORS directive to my nginx file for as simple static HTML site. (taken from here http://enable-cors.org/server_nginx.html)

Would there be a reason why it would complain about the first add_header directive saying 'add_header" directive is not allowed here'

My config file sample

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;
    }
}

回答1:

add_header has to be placed under either http, server, location or if in location block.

You are placing in under if in server. Move them under the location block.

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;
        }
    }
}

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



回答2:

The rule if in location can be bypassed by some tricks, so that you don't have to write/include CORS rules in every location block.

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;
}

This works because nginx will not return a header if its value is an empty string.



回答3:

Firstly, let me say that after looking around the web, I found this answer popping up everywhere:

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

However, I have decided to answer this question with a separate answer as I only managed to get this particular solution working after putting in about ten more hours looking for a solution.

It seems that Nginx doesn't define any [correct] font MIME types by default. By following this tuorial I found I could add the following:

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

To my etc/nginx/mime.types file.

As stated, the above solution then worked. Obviously, this answer is aimed at sharing fonts but it's definitely worth checking to see if the MIME type is defined (correctly) for any other resource you're struggling with too.



标签: nginx