部署至Heroku的Express API出现str.charAt is not a function错误,带参数路由无法正常响应
str.charAt is not a function错误 让我们一步步拆解你的问题,找到根源并解决:
核心错误原因分析
你遇到的str.charAt is not a function错误,结合路由无响应的表现,本质是数据库连接配置错误引发的连锁问题,再加上错误处理不完善,导致客户端一直处于等待状态。具体来说:
1. 数据库环境配置逻辑完全写反
看你的db.js代码:
const conn = new Pool({ connectionString: process.env.NODE_ENV === "production" ? devConfig : proConfig });
这里的逻辑搞反了!当NODE_ENV为production(也就是Heroku生产环境)时,你用的是本地开发的devConfig;而本地开发时,反而用的是生产环境的proConfig(依赖DATABASE_URL变量)。本地如果没正确配置DATABASE_URL,数据库连接会直接失败,执行pool.query时就会抛出错误。
2. 开发环境连接字符串存在多余空格
你的devConfig里:
const devConfig = `postgresql://${process.env.PG_USER}: ${process.env.PG_PASSWORD}@${process.env.PG_HOST}: ${process.env.PG_PORT}/${process.env.PG_DATABASE}`;
注意${process.env.PG_PASSWORD}前的空格,还有${process.env.PG_PORT}前的空格——这些多余的空格会导致PostgreSQL无法正确解析连接字符串,进而触发字符串处理相关的错误(也就是你看到的str.charAt is not a function)。
3. 错误处理未给客户端返回响应
在API路由的catch块里,你只打印了error.message,但没有给客户端发送任何响应:
catch (error) { console.log(error.message); };
这就导致浏览器发起请求后,一直等待服务器返回结果,但服务器永远不会响应,所以你看到请求无响应、控制台无报错的现象。
分步修复方案
1. 修正数据库连接配置(db.js)
把环境判断逻辑反过来,同时去掉连接字符串里的多余空格:
const { Pool } = require('pg'); require("dotenv").config(); // 去掉多余空格,确保连接字符串格式正确 const devConfig = `postgresql://${process.env.PG_USER}:${process.env.PG_PASSWORD}@${process.env.PG_HOST}:${process.env.PG_PORT}/${process.env.PG_DATABASE}`; const proConfig = { connectionString: process.env.DATABASE_URL }; // 修正逻辑:生产环境用proConfig,开发环境用devConfig const conn = new Pool({ connectionString: process.env.NODE_ENV === "production" ? proConfig.connectionString : devConfig }); module.exports = conn;
本地开发时,确保.env文件里的PG_USER、PG_PASSWORD、PG_HOST、PG_PORT、PG_DATABASE变量都正确配置,且本地PostgreSQL服务正在运行。
2. 完善错误处理,给客户端返回响应
修改API路由的catch块,在打印完整错误的同时,给客户端返回500错误和错误信息:
app.get("/data/:date/:tier", async (req, res) => { try { const { date, tier } = req.params; const allData = await pool.query( "SELECT * FROM smogon_usage_stats WHERE date=$1 AND tier=$2", [date, tier] ); const results = allData.rows; const output = { "data": Object.fromEntries( results.map( item => [item.pokemon, item] ) ) }; res.json(output); } catch (error) { console.error(error); // 打印完整错误信息,方便排查 res.status(500).json({ error: error.message }); // 给客户端返回错误响应 }; });
这样浏览器就能收到明确的错误提示,而不是一直处于无响应状态。
3. 本地测试验证
- 启动本地PostgreSQL服务,确认
.env配置正确 - 重新运行
node index.js - 访问
localhost:5000/data/2018-10/gen6ou,现在应该能看到正确的响应,或者明确的错误提示
4. Heroku部署注意事项
- 确保已在Heroku上添加PostgreSQL插件:执行
heroku addons:create heroku-postgresql:hobby-dev - Heroku会自动设置
NODE_ENV为production,无需手动配置 - 部署前可运行
heroku run node -e "console.log(process.env.DATABASE_URL)",验证DATABASE_URL是否正常存在
额外优化建议
- 本地开发时,安装
cross-env包,在package.json脚本里设置开发环境:"scripts": { "start": "node index.js", "dev": "cross-env NODE_ENV=development node index.js" } - 用
console.error打印错误,这样错误信息会在终端高亮显示,更易识别
内容的提问来源于stack exchange,提问作者nos codemos




