Docker-Compose环境下前端服务无法调用后端API求助
解决React前端无法调用Docker-Compose部署的Django API问题
核心问题分析
问题根源集中在两点:
- Docker网络地址解析逻辑:前端容器内的
localhost指向容器自身,而非主机或后端容器;即使浏览器直接访问主机端口3000,也可能因CORS配置过时导致请求被拦截。 - Django CORS配置版本不兼容:你使用的
CORS_ORIGIN_WHITELIST在django-cors-headersv3.0+版本已被弃用,导致跨域规则未实际生效。
分步解决方案
1. 修正Django配置
更新settings.py,适配新版CORS规则并放宽主机访问限制:
ALLOWED_HOSTS = ["0.0.0.0", "localhost", "backend"] # 加入后端服务名,支持容器间解析 INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "corsheaders", ] # 替换过时的CORS_ORIGIN_WHITELIST为新版配置项 CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://frontend:3000", # 加入前端服务名,支持容器内跨域 ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "corsheaders.middleware.CorsMiddleware", # 确保此中间件位于CommonMiddleware之前 "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ]
2. 调整前端API请求地址
根据运行场景选择对应地址:
- 浏览器直接访问主机3000端口(开发模式):保持
http://localhost:8000,但需确保主机防火墙未拦截8000端口,且Docker端口映射正常。 - 前端容器内访问后端:使用Docker Compose服务名
backend作为地址(Compose默认网络支持服务名解析):
const App = () => { const [currentTime, setCurrentTime] = useState(0); const [currentDate, setCurrentDate] = useState(0); useEffect(() => { fetch(`http://backend:8000`) .then((res) => res.json()) .then((data) => { setCurrentTime(data.time); setCurrentDate(data.date); }) .catch(err => console.error("API请求失败:", err)); // 新增错误捕获,方便排查 }, []); return ( <div className="App"> <header className="App-header"> <p> The date is {currentDate} and the time is {currentTime}. </p>{" "} <br /> </header> </div> ); };
推荐用环境变量统一管理API地址,比如在
docker-compose.yml中给前端添加REACT_APP_API_URL=http://backend:8000,避免代码硬编码。
3. 修复Docker Compose挂载路径错误
你的前端容器挂载路径与Dockerfile的WORKDIR不匹配,修正后确保代码热更新正常:
services: frontend: build: ./frontend ports: - "3000:3000" volumes: - ./frontend:/app # 与Dockerfile的WORKDIR保持一致 depends_on: - backend environment: - REACT_APP_API_URL=http://backend:8000 backend: build: ./backend ports: - "8000:8000" volumes: - ./backend:/app # 与Dockerfile的WORKDIR保持一致 command: "poetry run python manage.py runserver 0.0.0.0:8000"
4. 验证容器间网络连通性
进入前端容器测试后端可达性,确认网络配置正常:
# 进入前端容器 docker-compose exec frontend sh # 测试后端服务 curl http://backend:8000
若能返回API响应,说明容器间网络正常,问题出在前端代码或CORS配置。
额外排查点
- 确认
django-cors-headers已正确安装:检查pyproject.toml或poetry.lock是否包含该依赖。 - 检查Windows防火墙是否允许Docker Desktop访问8000、3000端口。
- 使用VS Code Dev Containers时,确认容器有权限访问主机Docker服务,端口映射已穿透到主机。
内容的提问来源于stack exchange,提问作者FinnM
相关产品推荐
相关产品推荐

