You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker-Compose环境下前端服务无法调用后端API求助

解决React前端无法调用Docker-Compose部署的Django API问题

核心问题分析

问题根源集中在两点:

  1. Docker网络地址解析逻辑:前端容器内的localhost指向容器自身,而非主机或后端容器;即使浏览器直接访问主机端口3000,也可能因CORS配置过时导致请求被拦截。
  2. Django CORS配置版本不兼容:你使用的CORS_ORIGIN_WHITELIST在django-cors-headers v3.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:57:19