修改React代码或刷新页面时Express返回404错误求助
问题
搭建Express后端服务器(端口4000)和React前端服务器,规划路径/react展示React内容、/对应Express内容。初始状态下两个路径均可正常访问,但修改React代码或刷新页面后,/react路径无法显示网页。终端中偶现服务器/客户端返回200状态码,但服务器会间歇性出现GET /react/static/js/bundle.js.map/、GET /ws的404错误,无论哪种情况网页都无法加载,严重影响开发进度。项目暂未进入部署阶段,不想修改构建相关设置;尝试过合并路径、配置React代理均无效,推测是服务端与客户端连接存在问题。此外,根目录的dev命令因"端口已被占用"错误无法使用,只能分别启动服务器和客户端。
问题分析
- 静态资源服务错误:当前Express将
/react指向React的public目录,但开发模式下React的资源由webpack-dev-server托管(端口3000),并非本地静态文件,导致Express无法找到bundle.js.map这类动态生成的资源。 - WebSocket请求未代理:React开发服务器使用WebSocket实现热更新,当前Express未处理
/ws请求,直接返回404,导致热更新失效。 - 单页应用刷新路由问题:React Router是客户端路由,刷新时浏览器直接向Express请求对应路径(如
/react/about),Express无对应路由,返回404。 - 端口占用处理不可靠:
npx kill-port未确保端口完全释放,导致dev命令启动失败。
解决方案
1. 配置Express代理React开发服务器
开发模式下,Express无需直接托管React静态文件,而是将/react路径的所有请求代理到React开发服务器(默认端口3000),同时支持WebSocket连接。
- 首先在server目录安装代理中间件:
npm install http-proxy-middleware --save-dev
- 修改server端
app.js,替换原有的/react路由和静态服务代码:
// 引入代理中间件 const { createProxyMiddleware } = require('http-proxy-middleware'); // 代理/react路径到React开发服务器,支持WebSocket app.use('/react', createProxyMiddleware({ target: 'http://localhost:3000', changeOrigin: true, pathRewrite: { '^/react': '' }, // 移除/react前缀,转发到React服务器根路径 ws: true // 处理WebSocket请求,解决GET /ws 404问题 })); // 处理React Router刷新的fallback:所有/react开头的GET请求都代理到React服务器 app.get('/react/*', createProxyMiddleware({ target: 'http://localhost:3000', changeOrigin: true, pathRewrite: { '^/react': '' } }));
2. 调整React路由的基础路径
确保React Router的路由匹配/react前缀,在React项目的src/index.js中设置basename:
import { BrowserRouter } from 'react-router-dom'; ReactDOM.createRoot(document.getElementById('root')).render( <BrowserRouter basename="/react"> <App /> </BrowserRouter> );
同时,暂时注释React项目package.json中的homepage字段(部署时再配置):
// "homepage": "/react",
3. 修复端口占用问题,恢复dev命令
修改根目录package.json的scripts,移除不可靠的kill-port,手动确保端口未被占用:
"scripts": { "init": "cd client && npm install && cd server && npm install", "client": "cd client && npm run start", "server": "cd server && npm start", "dev": "concurrently -k \"npm run server\" \"npm run client\"" }
若仍出现端口占用,手动清理:
- Windows:
# 查找3000/4000端口的进程ID netstat -ano | findstr :3000 netstat -ano | findstr :4000 # 杀死进程(替换<PID>为查到的进程ID) taskkill /F /PID <PID>
- Mac/Linux:
# 查找3000/4000端口的进程ID lsof -i :3000 lsof -i :4000 # 杀死进程(替换<PID>为查到的进程ID) kill -9 <PID>
4. 验证效果
- 先启动Express服务器:
npm run server(根目录执行) - 再启动React开发服务器:
npm run client(根目录执行) - 访问
http://localhost:4000/react,修改React代码测试热更新,刷新页面验证路由是否正常,检查终端是否还有404错误。
内容的提问来源于stack exchange,提问作者NS H
相关产品推荐
相关产品推荐

