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-servernginx的日志,都成功向上游服务器发出请求???

我的所有挖掘都让我找到了解决上述任一问题的解决方案,但没有解决这两个问题时该怎么做。我被难住了。

如有必要,提供更多背景信息: 我正在使用 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
    }
}