Docker Compose网络中JavaScript HTTP请求无法解析主机名
问题原因
你踩了Docker新手常犯的一个坑:前端代码是在用户的浏览器里运行的,不是在web容器内部。
浏览器解析api这个主机名时,用的是你本地电脑的DNS系统,它根本不知道Docker Compose创建的私有内部网络,自然找不到这个服务。而docker-compose exec web curl api是在web容器内部执行的,属于Docker的私有网络环境,所以能正常解析并访问。
解决方案
方案1:反向代理(推荐,满足你“仅容器内访问API”的需求)
开发环境(Vue本地调试)
在Vue项目根目录的vue.config.js中配置代理,让前端请求自动转发到API服务:
module.exports = { devServer: { proxy: { '/transcribe': { target: 'http://api:4999', changeOrigin: true } } } }
然后把前端的fetch请求改成相对路径:
fetch("/transcribe", { method:'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data) }) // 后续处理代码保持不变
这样本地开发时,Vue的dev服务器会自动把/transcribe请求转发到Docker内部的api服务。
生产环境(构建后部署到容器)
给web容器配置Nginx反向代理,步骤如下:
- 在
TranscriptionFrontend目录下创建nginx.conf文件:
server { listen 4998; root /usr/share/nginx/html; index index.html; # 将/transcribe请求转发到Docker内部的api服务 location /transcribe { proxy_pass http://api:4999; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 处理Vue单页应用的路由刷新问题(如果用了前端路由) location / { try_files $uri $uri/ /index.html; } }
- 修改web容器的Dockerfile,把构建好的Vue静态文件和Nginx配置复制进去:
# 第一步:构建Vue项目 FROM node:18-alpine as builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 第二步:部署到Nginx FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 4998
web容器启动后,Nginx会自动把前端的/transcribe请求转发到api服务,前端代码同样使用相对路径即可。
方案2:临时调试用(不推荐生产环境)
如果只是临时调试,可以给api服务添加端口映射,让主机能直接访问:
version: "3.8" services: web: build: ./TranscriptionFrontend ports: - 4998:4998 api: build: ./TranscriptionAPI ports: - 4999:4999 # 添加这行端口映射
然后前端请求改成http://localhost:4999/transcribe,这样浏览器能通过本地端口访问API,但缺点是API暴露到了主机网络,不符合你“仅容器内访问”的需求。
方案3:修改本地hosts(不推荐多人协作场景)
在本地电脑的hosts文件里添加一行:127.0.0.1 api,这样浏览器会把api解析成本地localhost,再配合方案2的端口映射也能访问。但这个方法需要每个使用项目的人都修改hosts,协作起来非常麻烦。
内容的提问来源于stack exchange,提问作者Insomnes
相关产品推荐
相关产品推荐

