我目前正在开发一个多容器项目,涉及react、django 和(最终)几个数据存储,这些数据存储全部容器化并与docker-compose 捆绑在一起。这都是在 vscode devcontainers 中开发的。主机操作系统是Windows 11。
我可以通过浏览器(以及 Django 的 API Web 界面)向我的 Django API 发出请求。但是我无法通过前端服务向 API 发出请求。使用 javascript fetch api,我无法向以下任何一个发出请求
localhost:8000
(注意:很多人都说这应该可以正常工作)0.0.0.0:8000
(注意:这至少会抛出 NS_ERROR_CONNECTION_REFUSED 错误,该错误仍然无法解决)host.docker.internal:8000
192.168.99.100:8000
172.24.0.2:8000
后端 Dockerfile
FROM python:3.10-alpine
ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY . .
RUN apk add poetry && poetry install
EXPOSE 8000
前端 Dockerfile
FROM node:lts-alpine
WORKDIR /app
COPY . .
RUN yarn install
EXPOSE 3000
CMD ["yarn", "start"]
docker-compose.yml
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/frontend
depends_on:
- backend
backend:
build: ./backend
ports:
- "8000:8000"
volumes:
- ./backend:/backend
command: "poetry run python manage.py runserver 0.0.0.0:8000"
Django 设置.py
ALLOWED_HOSTS = ["0.0.0.0"] # ADDED CORS
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"corsheaders", # ADDED CORS
]
CORS_ORIGIN_WHITELIST = [
"http://localhost:3000" # ADDED CORS
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware", # ADDED CORS
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
反应应用程序.tsx
const App = () => {
const [currentTime, setCurrentTime] = useState(0);
const [currentDate, setCurrentDate] = useState(0);
useEffect(() => {
fetch(`http://localhost:8000`)
.then((res) => res.json())
.then((data) => {
setCurrentTime(data.time);
setCurrentDate(data.date);
});
}, []);
return (
<div className="App">
<header className="App-header">
<p>
The date is {currentDate} and the time is {currentTime}.
</p>{" "}
<br />
</header>
</div>
);
};
Django 的 settings.py 需要以下内容,因为唯一可访问的端口来自
http://host.docker.internal
域。不是许多教程和文档中描述的localhost
。
CORS_ORIGIN_WHITELIST = [
...,
"http://host.docker.internal:3000"
]