React前端向Node.js后端发POST请求遇404错误求助
404错误排查:React前端POST请求无法抵达Node.js后端
问题背景
使用React前端 + Node.js后端开发应用,添加交易时发送POST请求出现Error: Request failed with status code 404,请求无法到达后端。
前端相关代码
触发请求的组件代码
<div className='transaction-new-trade-container input-container-style-dash'> <h2>Add new trade</h2> <label>Stock symbol</label> <input type='text' value={newTrade.symbol} name='symbol' onChange={handleInputChange} /> <label>Shares amount</label> <input type='number' value={newTrade.amount === 0 ? '' : newTrade.amount} name='amount' onChange={handleInputChange} /> <label>Entry price</label> <input type='number' value={newTrade.entryPrice === 0 ? '' : newTrade.entryPrice} name='entryPrice' onChange={handleInputChange} /> <label>Exit price</label> <input type='number' value={newTrade.exitPrice === 0 ? '' : newTrade.exitPrice} name='exitPrice' onChange={handleInputChange} /> <button className='btn-style-3' onClick={() => onAddingNewTrade(newTrade)} > Add new trade </button> </div>
onAddingNewTrade函数
function onAddingNewTrade(newTrade) { newTrade.day = utilService.getDate() newTrade.pl = tradeService.calculatePL( newTrade.symbol, newTrade.amount, newTrade.entryPrice, newTrade.exitPrice ) newTrade.percentage = tradeService.calculatePercentageChange( newTrade.entryPrice, newTrade.exitPrice ) newTrade.timestamp = Date.now() addTrade(newTrade) }
addTrade函数
export async function addTrade(trade) { try { const savedTrade = await tradeService.save(trade) console.log('Added Trade', savedTrade) store.dispatch(getActionAddTrade(savedTrade)) return savedTrade // maybe no need for it - consider removing later } catch (err) { console.log('Cannot add trade', err) throw err } }
发送POST请求的save函数
async function save(trade) { var savedTrade if (trade._id) { savedTrade = await httpService.put(`trade/${trade._id}`, trade) // if trade has Id so update } else { console.log('sending request to backend', trade) savedTrade = await httpService.post('/trade', trade) // if trade does not has id create add new trade } return savedTrade }
后端相关代码
服务器路由挂载
app.use('/api/trade', tradeRoutes)
交易路由文件
import express from 'express' import { requireAuth } from '../../middlewares/requireAuth.middleware.mjs' import { log } from '../../middlewares/logger.middleware.mjs' import { getTrades, getTradeById, addTrade, updateTrade, removeTrade, addTradeMsg, removeTradeMsg } from './trade.controller.mjs' const router = express.Router() // We can add a middleware for the entire router: // router.use(requireAuth) router.get('/', log, getTrades) router.get('/:id', getTradeById) router.post('/trade',requireAuth, addTrade) // add new trade router.put('/:id', requireAuth, updateTrade) // update existing trade router.delete('/:id', requireAuth, removeTrade) // router.delete('/:id', requireAuth, requireAdmin, removeTrade) router.post('/:id/msg', requireAuth, addTradeMsg) router.delete('/:id/msg/:msgId', requireAuth, removeTradeMsg) export const tradeRoutes = router
addTrade控制器函数
export async function addTrade(req, res) { const {loggedinUser} = req console.log('from front', req.body) try { const trade = req.body trade.owner = loggedinUser const addedTrade = await tradeService.add(trade) res.json(addedTrade) } catch (err) { logger.error('Failed to add trade', err) res.status(400).send({ err: 'Failed to add trade' }) } }
错误原因及解决方法
核心问题:请求路径不匹配
后端实际暴露的POST接口完整路径是/api/trade/trade,但前端请求的路径是/trade,两者完全不匹配,导致404错误。
具体逻辑拆解:
- 后端服务器给
tradeRoutes挂载了前缀/api/trade:app.use('/api/trade', tradeRoutes) - 交易路由文件中,POST路由定义为
router.post('/trade', ...),因此完整接口路径是/api/trade/trade - 前端
save函数中,POST请求路径仅为/trade,既缺少/api前缀,也未匹配后端的完整路径结构
修复方案
方案一:直接调整前端请求路径
将前端save函数中的POST请求路径改为后端完整接口路径:
async function save(trade) { var savedTrade if (trade._id) { savedTrade = await httpService.put(`/api/trade/${trade._id}`, trade) } else { console.log('sending request to backend', trade) savedTrade = await httpService.post('/api/trade/trade', trade) } return savedTrade }
方案二:优化后端路由结构(更符合RESTful规范)
/api/trade已经代表交易资源集合,POST请求直接用根路径即可,修改交易路由文件中的POST路由:
// 替换原有的 router.post('/trade',requireAuth, addTrade) router.post('/',requireAuth, addTrade)
此时完整接口路径变为/api/trade,前端同步调整请求路径:
async function save(trade) { var savedTrade if (trade._id) { savedTrade = await httpService.put(`/api/trade/${trade._id}`, trade) } else { console.log('sending request to backend', trade) savedTrade = await httpService.post('/api/trade', trade) } return savedTrade }
额外检查项
- 确认开发环境下前端是否配置了代理,确保
/api前缀能正确转发到后端服务器 - 检查后端服务器是否正常启动,端口与前端代理配置一致
- 若仍有问题,可临时注释
requireAuth中间件,排除权限拦截导致的路径匹配问题
内容的提问来源于stack exchange,提问作者Dor
相关产品推荐
相关产品推荐

