nginx错误:“ Access-Control-Allow-Origin”标头包含多个值

时间:2018-07-31 10:06:03

标签: nginx

我曾经以这种配置运行nginx v1.6:

location / {
    alias                   /some/path/;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_set_header        uuid $uuid;
    more_set_headers        'Access-Control-Allow-Origin: $http_origin';
    more_set_headers        'Access-Control-Allow-Credentials: true';
    more_set_headers        'Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS';
    more_set_headers        'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,access_token,__setXHR_';
    if ($request_method = 'OPTIONS') {
        more_set_headers    'Access-Control-Allow-Origin: $http_origin';
        more_set_headers    'Access-Control-Allow-Credentials: true';
        more_set_headers    'Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS';
        more_set_headers    'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,access_token,__setXHR_';
        add_header          'Access-Control-Max-Age' 1728000;
        add_header          'Content-Type' 'text/plain charset=UTF-8';
        add_header          'Content-Length' 0;
        return              204;
    }
}

自从我升级到nginx v1.10.x以来,“ more_set_headers”不再起作用,我一直通过add_header'blablabla'对其进行了更改;

现在看起来像这样:

location / {
    alias                   /some/path/;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_set_header        uuid $uuid;
    add_header              'Access-Control-Allow-Origin: $http_origin' always;
    add_header              'Access-Control-Allow-Credentials: true' always;
    add_header              'Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS' always;
    add_header              'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,access_token,__setXHR_' always;
    if ($request_method = 'OPTIONS') {
        add_header          'Access-Control-Allow-Origin: $http_origin' always;
        add_header          'Access-Control-Allow-Credentials: true' always;
        add_header          'Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS' always;
        add_header          'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,access_token,__setXHR_' always;
        add_header          'Access-Control-Max-Age' 1728000;
        add_header          'Content-Type' 'text/plain charset=UTF-8';
        add_header          'Content-Length' 0;
        return              204;
    }
}

但是,当我现在登录网站时,出现此错误:

  

无法加载https://mywebsite/auth/login:对预检请求的响应未通过访问控制检查:“ Access-Control-Allow-Origin”标头包含多个值“ $ http_origin:始终”,但仅允许一个。因此,不允许访问来源“ https://mywebsite”。

我应该进行哪些更改才能使其正常工作?我有点卡在那里。

5 个答案:

答案 0 :(得分:1)

我不记得我今天早些时候在哪里读过这篇文章。我丢了页。但是,对于我来说,答案是:

  

您不能在堆栈中设置多个cors标头。蛋。 nginx和django。他们中只有一个可以胜任,否则将会有多个   标题中的值。

通过从我的api中删除cors处理,仅让nginx这样做,错误消失了。

我将对其进行更新,并在找到它时参考其源代码。 由于在多个论坛和平台上都很难在Google上找到此信息,因此,我决定在SO上回答这个显而易见的话题。

答案 1 :(得分:0)

但是您要两次添加相同的标头。
在任何情况下,都无需在请求方法检查后添加标头。
因此,我相信您的配置应如下所示:

location / {
    alias                   /some/path/;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_set_header        uuid $uuid;
    add_header              'Access-Control-Allow-Origin: $http_origin' always;
    add_header              'Access-Control-Allow-Credentials: true' always;
    add_header              'Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS' always;
    add_header              'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,access_token,__setXHR_' always;
    if ($request_method = 'OPTIONS') {
        add_header          'Access-Control-Max-Age' 1728000;
        add_header          'Content-Type' 'text/plain charset=UTF-8';
        add_header          'Content-Length' 0;
        return              204;
    }
}

答案 2 :(得分:0)

找到解决方案。

这只是“简单”的语法错误。

add_header              'Access-Control-Allow-Origin: $http_origin' always;

实际上必须是

add_header              'Access-Control-Allow-Origin' '$http_origin' always;

当然对所有其他add_header条目进行相同的修改。

答案 3 :(得分:0)

基于对傻瓜(first answer)的解释。
我通过块nginx解决了这个问题,可以通过从nginx配置中删除proxy_set_header Host $host;来设置标头

server {
   ....
   location / {
      ...
   #  proxy_set_header Host $host;  
   }}
 

答案 4 :(得分:0)

add_header 将附加值而不是替换它