使用 docker compose 启动时,CORS 会阻止从前端到 Flask 服务器的请求

问题描述 投票:0回答:5

描述 我有一个 React 应用程序发出以下请求:

await axios.get(`${process.env.REACT_APP_MASTER_HOST}/api/agl-history`, { headers: { Authorization: `Bearer ${token}` }, data: { label, date } });

在某些情况下它可以工作,但是当后端以

docker-compose up -d
启动时,它会在 Chrome 中给出以下内容:

Access to XMLHttpRequest at 'http://localhost:8080/api/agl-history' from origin 'http://localhost:3000' 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.

什么时候起作用

  • 当我使用
    sudo docker build . -t test
    手动构建图像并运行时,
    sudo docker run -p 8080:8080 -t test
    ,它完美运行
  • 当我使用
    flask run --host=0.0.0.0
  • 运行 Flask 服务器时

不起作用时

  • docker-compose up -d

// docker-compose.yml,相关服务为

master

version: "3.9"
services:
  agl-history:
    depends_on:
        - mariadb
    build: ./agl-history
    restart: on-failure
    networks:
        - main
  master:
    depends_on:
        - mariadb
    build: ./master
    restart: on-failure
    ports:
        - 8080:8080
    networks:
        - main
  mariadb:
    image: "mariadb:10.5.10"
    restart: on-failure
    environment: 
        MYSQL_ROOT_PASSWORD: ${MARIADB_PASSW}
    ports:
        - 3306:3306
    volumes:
        - /var/lib/docker/volumes/add3-data:/var/lib/mysql
    networks:
        - main
networks:       
    main:
        driver: bridge

// Dockerfile

FROM python:3.9.5-buster

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

COPY . .

ENV FLASK_RUN_PORT 8080
ENV FLASK_APP source/server_config.py

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

// Flask 端点

from datetime import date
from flask import Flask
from flask import jsonify
from datetime import datetime
from flask_cors import CORS

# app reference
app = Flask(__name__)
cors = CORS(app)

# This method executes before any API request
@app.before_request
def before_request():
    print('before API request')

@app.route('/api/agl-history', methods=['GET'])
def get_agl_history():
    print('during')
    response = jsonify([
        {
            'id': 1,
            'customerId': 777,
            'campaignName': 'Test campaing',
            'adGroupName': 'Test ad group',
            'execDate': datetime.now(),
            'label': '92'
        }
    ]
    )
    return response

# This method executes after every API request.
@app.after_request
def after_request(response):
    return response

注释

  • React 前端和服务器后端最终将在不同的主机上运行

我做错了什么?任何帮助是极大的赞赏!谢谢!

docker flask docker-compose cors
5个回答
0
投票

我认为问题来自于 Flask 后端,它是 CORS 标头。我建议在您的 Flask 命令中使用 --host=127.0.0.1 。另外,请检查this答案,它提供了很多信息。


0
投票

可能是浏览器正在发送预检(选项)请求,因为你有授权标头,我之前在使用 React dev 服务器和 Express 时也遇到过同样的问题,

我解决了问题,选项路由在同一路径上:

访问控制请求标头:授权

但我在这里可能是错的,因为 cors 是令人困惑的事情:)


0
投票

当来源(前端 localhost:3000)与 API 来源(localhost:8080)不同时,浏览器发出预检请求(选项调用)

对于开发,您可以允许 Flask 服务器中的所有源。这是默认配置。看来您的工作场景就是这种情况

但是当通过 docker-compose 运行时,flask 服务器的主机名将是

master
。从您的失败场景来看,flask 似乎只接受来自该主机名的信息。

所以在生产环境中部署时我建议添加 cors origin 配置 allowed origin 作为前端域

对于您的 docker-compose 场景,您可以在 Flask 服务器中进行以下配置

CORS_ORIGINS: “localhost:3000”

0
投票

我没有意识到 docker-compose 默认情况下不会重建映像,因此我使用的是未启用 CORS 的旧版本。

解决该问题所需的唯一更改是:

cors = CORS(app, origins="*")

启动 Flask 服务器时。然后,启动服务:

sudo docker-compose up -d --build master

0
投票

我也遇到同样的问题,请问你找到解决办法了吗?

© www.soinside.com 2019 - 2024. All rights reserved.