描述 我有一个 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
不起作用时
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
注释
我做错了什么?任何帮助是极大的赞赏!谢谢!
我认为问题来自于 Flask 后端,它是 CORS 标头。我建议在您的 Flask 命令中使用 --host=127.0.0.1 。另外,请检查this答案,它提供了很多信息。
可能是浏览器正在发送预检(选项)请求,因为你有授权标头,我之前在使用 React dev 服务器和 Express 时也遇到过同样的问题,
我解决了问题,选项路由在同一路径上:
访问控制请求标头:授权
但我在这里可能是错的,因为 cors 是令人困惑的事情:)
当来源(前端 localhost:3000)与 API 来源(localhost:8080)不同时,浏览器发出预检请求(选项调用)
对于开发,您可以允许 Flask 服务器中的所有源。这是默认配置。看来您的工作场景就是这种情况
但是当通过 docker-compose 运行时,flask 服务器的主机名将是
master
。从您的失败场景来看,flask 似乎只接受来自该主机名的信息。
所以在生产环境中部署时我建议添加 cors origin 配置 allowed origin 作为前端域
对于您的 docker-compose 场景,您可以在 Flask 服务器中进行以下配置
CORS_ORIGINS: “localhost:3000”
我没有意识到 docker-compose 默认情况下不会重建映像,因此我使用的是未启用 CORS 的旧版本。
解决该问题所需的唯一更改是:
cors = CORS(app, origins="*")
启动 Flask 服务器时。然后,启动服务:
sudo docker-compose up -d --build master
我也遇到同样的问题,请问你找到解决办法了吗?