Access-Control-Allow-Origin Header 不存在时 NGINX CORS 策略失败,但在 header 存在时多次设置它
NGINX CORS Policy Fails when Access-Control-Allow-Origin Header is not present, but then sets it multiple times when header is present
正如标题所言,但对于上下文:
我确实可以访问上游资源,我是允许那里的所有来源。
当我的 NGINX conf 不 包含指令时 add_header 'Access-Control-Allow-Origin' '*';
我的浏览器告诉我:
Access to XMLHttpRequest at 'http://localhost/{{ upstream_path_redacted }}' from
origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight
request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is
present on the requested resource.
当我包含上述指令时,我的浏览器会告诉我
Access to XMLHttpRequest at 'http://localhost/{{ upstream_path_redacted }}' from origin 'http://localhost:8080' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8080, *', but only one is allowed.
第二个问题有道理。正如我所说,我是 允许上游服务器上的所有来源。因此我不明白为什么删除指令会导致第一个问题。
我的nginx.conf
:
events {}
http {
upstream my-upstream-service {
server my-upstream-service:5000;
}
server {
listen 80 default_server;
location / {
# this works fine. just included as base case.
return 200 'ok';
add_header Content-Type text/plain;
add_header 'Access-Control-Allow-Origin' '*';
}
location /upstream {
# removing the next uncommented line results in 'missing header' issue.
# keeping it results in 'multiple header' issue.
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://my-upstream-service;
}
}
}
更让我困惑的是:查看my-upstream-server
和nginx
的日志,都成功向上游服务器发出请求???
我的所有挖掘都让我找到了解决上述任一问题的解决方案,但没有解决这两个问题时该怎么做。我被难住了。
如有必要,提供更多背景信息:
我正在使用 docker-compose
来部署这些服务(包括 front-end,这是一个 Vue SPA)。
my-upstream-service
是一个 Flask
网络服务器,使用 Flask-Cors。
这是docker-compose.yml
---
version: '3.8'
networks:
gateway-service:
driver: bridge
services:
my-upstream-service:
build:
context: path/to/context/
dockerfile: path/to/dockerfile
ports:
- "5000:5000"
expose:
- "5000"
networks:
- gateway-service
frontend:
build:
context: /path/to/context
dockerfile: /path/to/dockerfile
ports:
- "8080:8080"
expose:
- "8080"
depends_on:
- gateway
networks:
- gateway-service
gateway:
image: nginx:1.19.8-alpine
volumes:
# this is where my nginx.conf lives.
- ./nginx/:/etc/nginx/
ports:
- "80:80"
environment:
- NGINX_PORT=80
depends_on:
- my-upstream-service
networks:
- gateway-service
我不确定为什么我在没有任何关于我的问题的反馈的情况下被否决,或者为什么我被否决。
无论如何,经过几个小时的键盘混搭后,我开始工作了。
本质上,也在 NGINX 反向代理后面服务 Vue 应用程序,虽然它产生了更多问题,但解决了上述长 运行.
中描述的问题
我不得不向我的 Vue 应用程序和我的 NGINX conf 添加额外的配置,以使 Vue 的所有开发功能能够完全运行。这是最终 NGINX conf 的最小版本:
events {}
http {
upstream upstream-service {
server upstream-service:5000;
}
upstream front-end {
server front-end:8080;
}
server {
listen 80 default_server;
location / {
proxy_pass http://front-end;
proxy_set_header Host localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host localhost;
proxy_set_header X-Forwarded-Server localhost;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_redirect off;
proxy_connect_timeout 90s;
proxy_read_timeout 90s;
proxy_send_timeout 90s;
}
location /sockjs-node {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://front-end;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /upstream {
proxy_pass http://upstream-service;
}
}
}
我还必须添加到我的 vue.config.js
:
module.exports = {
devServer: {
disableHostCheck: true
}
}
正如标题所言,但对于上下文:
我确实可以访问上游资源,我是允许那里的所有来源。
当我的 NGINX conf 不 包含指令时 add_header 'Access-Control-Allow-Origin' '*';
我的浏览器告诉我:
Access to XMLHttpRequest at 'http://localhost/{{ upstream_path_redacted }}' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
当我包含上述指令时,我的浏览器会告诉我
Access to XMLHttpRequest at 'http://localhost/{{ upstream_path_redacted }}' from origin 'http://localhost:8080' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8080, *', but only one is allowed.
第二个问题有道理。正如我所说,我是 允许上游服务器上的所有来源。因此我不明白为什么删除指令会导致第一个问题。
我的nginx.conf
:
events {}
http {
upstream my-upstream-service {
server my-upstream-service:5000;
}
server {
listen 80 default_server;
location / {
# this works fine. just included as base case.
return 200 'ok';
add_header Content-Type text/plain;
add_header 'Access-Control-Allow-Origin' '*';
}
location /upstream {
# removing the next uncommented line results in 'missing header' issue.
# keeping it results in 'multiple header' issue.
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://my-upstream-service;
}
}
}
更让我困惑的是:查看my-upstream-server
和nginx
的日志,都成功向上游服务器发出请求???
我的所有挖掘都让我找到了解决上述任一问题的解决方案,但没有解决这两个问题时该怎么做。我被难住了。
如有必要,提供更多背景信息:
我正在使用 docker-compose
来部署这些服务(包括 front-end,这是一个 Vue SPA)。
my-upstream-service
是一个 Flask
网络服务器,使用 Flask-Cors。
这是docker-compose.yml
---
version: '3.8'
networks:
gateway-service:
driver: bridge
services:
my-upstream-service:
build:
context: path/to/context/
dockerfile: path/to/dockerfile
ports:
- "5000:5000"
expose:
- "5000"
networks:
- gateway-service
frontend:
build:
context: /path/to/context
dockerfile: /path/to/dockerfile
ports:
- "8080:8080"
expose:
- "8080"
depends_on:
- gateway
networks:
- gateway-service
gateway:
image: nginx:1.19.8-alpine
volumes:
# this is where my nginx.conf lives.
- ./nginx/:/etc/nginx/
ports:
- "80:80"
environment:
- NGINX_PORT=80
depends_on:
- my-upstream-service
networks:
- gateway-service
我不确定为什么我在没有任何关于我的问题的反馈的情况下被否决,或者为什么我被否决。
无论如何,经过几个小时的键盘混搭后,我开始工作了。
本质上,也在 NGINX 反向代理后面服务 Vue 应用程序,虽然它产生了更多问题,但解决了上述长 运行.
中描述的问题我不得不向我的 Vue 应用程序和我的 NGINX conf 添加额外的配置,以使 Vue 的所有开发功能能够完全运行。这是最终 NGINX conf 的最小版本:
events {}
http {
upstream upstream-service {
server upstream-service:5000;
}
upstream front-end {
server front-end:8080;
}
server {
listen 80 default_server;
location / {
proxy_pass http://front-end;
proxy_set_header Host localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host localhost;
proxy_set_header X-Forwarded-Server localhost;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_redirect off;
proxy_connect_timeout 90s;
proxy_read_timeout 90s;
proxy_send_timeout 90s;
}
location /sockjs-node {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://front-end;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /upstream {
proxy_pass http://upstream-service;
}
}
}
我还必须添加到我的 vue.config.js
:
module.exports = {
devServer: {
disableHostCheck: true
}
}