当 Access-Control-Allow-Origin 标头不存在时,NGINX CORS 策略失败,但在标头存在时将其设置多次

问题描述

正是标题所说的,但为了上下文:

确实有权访问上游资源,并且我允许那里的所有来源。

当我的 Nginx 配置包含指令 add_header 'Access-Control-Allow-Origin' '*'; 时,我的浏览器告诉我:

在 'http://localhost/{{ upstream_path_redacted }}' 处访问 XMLHttpRequest 来源 'http://localhost:8080' 已被 CORS 策略阻止:对预检的响应 请求未通过访问控制检查:没有“Access-Control-Allow-Origin”标头 出现在请求的资源上。

当我确实包含上述​​指令时,我的浏览器会告诉我

从源 'http://localhost:8080' 访问 XMLHttpRequest at 'http://localhost/{{ upstream_path_redacted }}' 已被 CORS 策略阻止:'Access-Control-Allow-Origin' 标头包含多个值 'http://localhost:8080,*',但只允许一个

第二个问题是有道理的。正如我所说,我允许上游服务器上的所有来源。因此,我不明白为什么删除指令会导致第一个问题。

我的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 来部署这些服务(包括前端,即 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
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...