React客户端经Nginx反向代理访问Node.js后端遇404错误排查
问题现象
React客户端在localhost:3000/login发起登录请求时返回404错误,浏览器控制台显示parsing_error,怀疑Nginx的location配置存在问题,调整后仍出现其他错误,需排查部署配置中的问题。
现有配置文件
nginx.conf
upstream loadbalancer { least_conn; server ws1:8081; server ws2:8082; server ws3:8083; } server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://loadbalancer/; proxy_buffering on; } }
docker-compose.yml
services: ws1: image: bark-mate-be environment: - APPID=1111 - APPPORT=8081 networks: - loadbalancing ports: - "8081" ws2: image: bark-mate-be environment: - APPID=2222 - APPPORT=8082 ports: - "8082" networks: - loadbalancing ws3: image: bark-mate-be environment: - APPID=3333 - APPPORT=8083 ports: - "8083" networks: - loadbalancing barkmatefrontend: image: bark-mate-fe ports: - "3000:80" networks: - loadbalancing depends_on: - db - ws1 - ws2 - ws3 db: volumes: - barkMate_db:/data/db image: mongo:latest ports: - "27017:27017" volumes: barkMate_db: networks: loadbalancing:
Dockerfile-client
FROM node:current-alpine as build WORKDIR /app COPY package*.json /app/ RUN npm install RUN npm ci --production COPY . . RUN npm run build FROM nginx:alpine-slim COPY --from=build /app/build/ /usr/share/nginx/html COPY --from=build /app/nginx/nginx.conf /etc/nginx/conf.d/default.conf
Dockerfile-server
FROM node:16 RUN mkdir -p /app WORKDIR /app COPY package*.json ./ RUN npm install --silent COPY . . EXPOSE 8080 CMD ["node", "server.js"]
问题排查与修复方案
1. Nginx反向代理路径匹配错误
当前location /api/配置中,proxy_pass http://loadbalancer/;会将请求路径中的/api/前缀移除后转发到后端。比如客户端请求/api/login,实际转发到后端的是http://loadbalancer/login。如果后端API路由本身带有/api前缀,就会出现404。
修复方式:
- 若后端API带
/api前缀,修改proxy_pass为不带末尾斜杠的形式,同时补充必要代理头避免后端识别异常:location /api/ { proxy_pass http://loadbalancer; proxy_buffering on; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } - 若后端API不带
/api前缀,需确保客户端请求路径以/api开头(比如请求/api/login而非/login),否则请求会被Nginx的location /块处理,返回React页面而非转发到后端。
2. Node.js后端端口配置不匹配
Dockerfile-server中声明EXPOSE 8080,但docker-compose给后端容器设置的环境变量是APPPORT=8081/8082/8083,需确认后端代码是否正确读取APPPORT并监听对应端口。如果后端实际监听8080,容器端口却配置为8081/8082/8083,会导致Nginx无法连接后端,出现502或404。
修复方式:
- 统一端口:要么将docker-compose中的
APPPORT改为8080,要么修改后端代码确保监听APPPORT指定的端口,同时可更新Dockerfile-server的EXPOSE为对应端口(或直接移除EXPOSE,它仅为声明,不影响实际监听)。
3. React客户端请求路径错误
客户端直接在localhost:3000/login发起请求,该请求会被Nginx的location /块处理,返回React的index.html,而非转发到后端API。正确的API请求路径应为localhost:3000/api/login。
修复方式:
在React代码中配置API基础路径为/api,确保所有API请求都以/api开头,比如登录请求应为${API_BASE_URL}/login。
4. 后端容器网络连通性验证
进入barkmatefrontend容器,执行curl http://ws1:8081/login(假设后端登录接口为/login),验证是否能正常获取响应。若无法连通,检查后端容器是否正常启动、端口是否正确监听。
内容的提问来源于stack exchange,提问作者Anthony T

