如何抑制来自后端服务器的 Nginx CORS 标头
Posted
技术标签:
【中文标题】如何抑制来自后端服务器的 Nginx CORS 标头【英文标题】:How supress Nginx CORS headers coming from backend server 【发布时间】:2017-11-12 19:56:20 【问题描述】:我正在使用 nginx 来为 Angular 2 客户端提供服务并将 rest API 路由到后端服务器。 在 Angular 开发模式下,我使用常规的“ng 服务器”,然后我应该向 Nginx 添加 CORS 支持,这种方式仅对作为外部服务器的 REST API 请求。
我的 Nginx 配置是:
server
listen 80;
resolver 127.0.0.1 valid=30s;
root /path/dist-nginx;
index index.html index.htm;
location /prometheus/prometheus/
if ($request_method = 'OPTIONS')
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
return 204;
if ($request_method = 'GET')
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://prometheus:9090/;
location /
try_files $uri $uri/ /index.html;
#try_files $uri $uri/ /index.html =404;
location /prometheus/prometheus 用于 api
位置/服务 Angular 客户端
它与第一个请求完美配合:
http://localhost:3330/prometheus/prometheus/metrics
表明至少 CORS 设置运行良好。
但是当客户端执行以下请求时:
http://localhost:3330/prometheus/prometheus/api/v1/query?query=http_request_size_bytes
我在浏览器中遇到了这个问题:
XMLHttpRequest cannot load
http://local.appcelerator.io:3330/prometheus/prometheus/api/v1/query?query=http_request_size_bytes.
The 'Access-Control-Allow-Origin' header contains multiple values '*,
http://localhost:4200', but only one is allowed. Origin
'http://localhost:4200' is therefore not allowed access.
查看我得到的请求的标头答案:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type
Access-Control-Allow-Headers:Accept, Authorization, Content-Type, Origin
Access-Control-Allow-Methods:GET, OPTIONS
Access-Control-Allow-Methods:GET, OPTIONS
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:Date
Connection:keep-alive
Content-Encoding:gzip
Content-Length:657
Content-Type:application/json
Date:Sun, 11 Jun 2017 05:39:34 GMT
Server:nginx/1.13.1
因此,除了我的之外,还添加了 3 个 CORS 标头字段:
Access-Control-Allow-Origin:*
Access-Control-Allow-Headers:Accept, Authorization, Content-Type, Origin
Access-Control-Allow-Methods:GET, OPTIONS
Angular客户端直接请求Nginx,中间没有人。
这两个请求在 nginx 上直接 curl 完美运行。
如果我执行第一个请求:
http://localhost:3330/prometheus/prometheus/metrics
在一个女巫失败后第二次,我没有错误,标题字段正常。
似乎问题特别是与此请求的链接:
http://localhost:3330/prometheus/prometheus/api/v1/query?query=http_request_size_bytes
似乎这里的后端服务器prometheus在响应url /api/v1上的api请求时会添加一些CORS标头
我怎样才能搭上他们?
感谢您提供任何有助于理解那里发生的事情的想法。
【问题讨论】:
你说中间什么都没有,但是proxy_pass http://prometheus:9090/;
在做什么呢?您确定由它提供的代码没有添加自己的 CORS 标头吗?
【参考方案1】:
最后,我可以确认添加的 CORS 字段来自 prometheus 后端。
因此,例如,当我请求 /prometheus/prometheus/metrics 时,我没有在标头中获得额外的 CORS 字段,但是当我请求 /prometheus/prometheus/api/v1 时,在标头中获得了额外的 CORS 字段
这是 Prometheus 不一致的行为,为了解决这个问题,我必须创建两个单独的位置,一个用于 /prometheus/prometheus/metrics 处理 CORS,一个用于 /prometheus/prometheus/api/v1,它不处理 CORS
【讨论】:
以上是关于如何抑制来自后端服务器的 Nginx CORS 标头的主要内容,如果未能解决你的问题,请参考以下文章
Angularjs + Spring-boot + nginx的CORS问题