You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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执行逻辑不符合预期。
修复方案
  1. 补全接口响应逻辑,数据库操作无论成功或失败都要返回对应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: '菜谱删除成功'
        })
    });
})
  1. 前端补充请求错误捕获逻辑,避免接口异常时无用户反馈,优化后代码如下:
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.')
    }
}
  1. 将修改后的代码重新部署到Heroku即可恢复正常,该故障和数据库体量大小无关,纯接口逻辑缺失导致。

内容的提问来源于stack exchange,提问作者Ads

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:36:17