Heroku部署Express服务Axios DELETE请求超时code=12如何解决
问题背景
- 前端为托管在Netlify的React应用,通过Axios发起DELETE请求删除数据库内存储的菜谱数据
- 后端为部署在Heroku的Express服务,数据库仅存储3条菜谱记录,所有GET接口均可在数秒内正常响应
- 调用删除接口时Heroku返回
code=12超时错误,Axios的请求成功回调完全不触发,控制台无成功日志输出
前端原有请求代码:
const handleDelete = async () => { if (warn) { await axios.delete('https://foodeii.herokuapp.com/api/delete/rec', { data: { id: props.recipe[0].ID } }).then((response) => { console.log('Recipe deleted successfully.') goBack(); }) } else { setWarn(true); alert('You will not be able to restore this recipe after deleting.') } }
后端原有接口代码:
// DELETE app.delete('/api/delete/rec', (req, res) => { const recipe = req.body.id; const sqlSelect = `DELETE FROM recipes WHERE ID = ${recipe}`; db.query(sqlSelect, (err, result) => { console.log(result); console.log(err); }); })
故障原因
核心原因是后端DELETE接口没有向客户端返回任何HTTP响应:
- Heroku对所有请求有默认30秒超时限制,接口执行完数据库操作后,没有调用
res.send()/res.json()/res.end()等方法结束响应,请求连接会一直处于挂起状态,达到超时阈值后就会被Heroku强制断开,返回code=12超时错误。 - 额外隐患:原有SQL语句采用直接字符串拼接的写法,存在SQL注入风险,不符合数据库操作规范。
- 潜在配置问题:如果未提前配置
express.json()中间件,接口无法正确解析请求体中的JSON参数,会导致req.body.id取值为undefined,不过该问题不会直接引发超时,只会导致SQL执行逻辑不符合预期。
修复方案
- 补全接口响应逻辑,数据库操作无论成功或失败都要返回对应HTTP状态码和结果,主动结束请求连接;同时改用参数化查询修复SQL注入隐患。修复后的后端代码如下:
// 提前在路由注册前加这行,确保能解析JSON格式请求体 app.use(express.json()) // 修复后的DELETE接口 app.delete('/api/delete/rec', (req, res) => { const recipeId = req.body.id; // 参数化查询,避免SQL注入 const deleteSql = `DELETE FROM recipes WHERE ID = ?`; db.query(deleteSql, [recipeId], (err, result) => { if (err) { console.error('删除菜谱SQL执行出错:', err); // 错误场景返回500状态 return res.status(500).json({ success: false, message: '菜谱删除失败' }) } console.log('删除结果:', result); // 成功场景返回200状态,结束响应 return res.status(200).json({ success: true, message: '菜谱删除成功' }) }); })
- 前端补充请求错误捕获逻辑,避免接口异常时无用户反馈,优化后代码如下:
const handleDelete = async () => { if (warn) { try { await axios.delete('https://foodeii.herokuapp.com/api/delete/rec', { data: { id: props.recipe[0].ID } }) console.log('Recipe deleted successfully.') goBack(); } catch (err) { console.error('删除请求失败:', err) alert('菜谱删除失败,请稍后重试') } } else { setWarn(true); alert('You will not be able to restore this recipe after deleting.') } }
- 将修改后的代码重新部署到Heroku即可恢复正常,该故障和数据库体量大小无关,纯接口逻辑缺失导致。
内容的提问来源于stack exchange,提问作者Ads
相关产品推荐
相关产品推荐

