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

Heroku上Node+Postgres应用查询时出现H13错误求助

解决Heroku部署Node+Postgres应用的H13连接错误

嘿,我来帮你揪出这个H13错误的根源!从你描述的情况来看——本地正常、硬编码返回没问题,问题肯定出在数据库查询的连接/处理环节,你的pg库用法有几个容易踩的坑,咱们一步步来改:

1. 修正Postgres的SSL配置

Heroku的Postgres实例对SSL的要求不是简单的ssl: true,默认的Node pg客户端会验证证书,但Heroku的证书不在Node的默认信任链里,直接开ssl: true会导致连接失败,进而让请求超时触发H13。你需要把SSL配置改成这样:

const client = new pg.Client({
  connectionString: process.env.DATABASE_URL,
  ssl: {
    rejectUnauthorized: false
  }
});

这个配置会跳过证书验证,完美适配Heroku的Postgres环境。

2. 改用连接池替代单次客户端连接

你现在每次请求都创建新客户端、连接、查询、关闭,这种方式在网络延迟或并发请求下很容易出问题——比如连接没及时关闭导致请求挂起超时。推荐用pg的连接池来管理连接,既高效又稳定:

// 注意:这个初始化要放在应用启动的地方,只执行一次!
const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: {
    rejectUnauthorized: false
  }
});

// 在路由处理里这样用
return pool.query(query, queryParams)
  .then(res => res.rows)
  .catch(e => {
    console.log(e.stack);
    throw e; // 一定要把错误抛出去,让Express处理并返回响应,不然请求会一直挂着
  });

连接池会自动复用连接,避免频繁创建销毁连接的开销,也能减少连接异常导致的超时问题。

3. 完善错误处理逻辑

你当前的catch块只打印了错误,但没有把错误返回给客户端,这会导致请求一直处于等待状态,直到Heroku判定超时触发H13。一定要在catch里抛出错误,或者调用next(e)让Express的错误中间件处理,确保请求能正常结束:

.catch(e => {
  console.error('数据库查询出错:', e.stack);
  throw new Error('查询失败,请稍后重试'); // 或者直接抛出原错误
});

关于路径末尾多了/的问题

这个其实是Heroku路由的正常行为,它会自动处理路径的末尾斜杠,一般不会影响功能。如果担心的话,可以在路由定义里加个?来匹配可选的斜杠,比如:

app.get('/your/path/?', (req, res) => {
  // 路由逻辑
});

按上面的步骤调整后,应该就能解决H13错误了,先从SSL配置和连接池改起,这两个是最可能的原因!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:37:54