Nodemailer生产环境发信报ERR_CONNECTION_REFUSED如何解决?
Nodemailer生产环境请求失败排查与解决方案
根因定位
你报错信息里请求地址仍然是http://localhost:3001/send,说明生产环境下process.env.NODE_ENV === 'production'的判断未生效,默认走了开发环境地址,这是最核心的问题,按以下步骤排查修复即可:
排查步骤
- 打开生产环境页面的F12控制台,执行
console.log(process.env.NODE_ENV),如果输出为undefined或者development,即可确认是前端环境变量注入失败导致的地址判断错误。 - 检查服务端启动日志,确认heroku上的后端服务是否正常启动,没有端口监听错误。
修复方案
1. 修正前端环境变量配置
不同前端框架对客户端环境变量的注入有规则限制:
- Create React App项目:所有环境变量必须加
REACT_APP_前缀,打包时才会注入到客户端代码 - Vite项目:所有环境变量必须加
VITE_前缀,通过import.meta.env访问,不能直接用process.env
临时验证方案:直接把url硬编码为heroku的服务地址,测试请求是否正常,若正常可100%确认是环境变量问题,后续再按框架规则配置环境变量即可。
2. 修正服务端端口监听逻辑
heroku不允许硬编码固定端口,必须通过环境变量process.env.PORT获取分配的端口,server.js中监听端口的代码要改成:
const PORT = process.env.PORT || 3001 app.listen(PORT, () => console.log(`服务启动在端口${PORT}`))
3. 配置服务端CORS规则
不要使用公共cors-anywhere代理,该类服务普遍有限流、停用的问题,直接在服务端安装cors包配置跨域即可:
const cors = require('cors') app.use(cors({ origin: process.env.NODE_ENV === 'production' ? '你的前端生产域名' : 'http://localhost:前端开发端口' }))
4. 优化前端请求代码
现有代码存在异步逻辑冗余、无错误捕获的问题,修正后的参考代码:
const submitEmail = async (e) => { e.preventDefault(); try { const url = process.env.NODE_ENV === 'production' ? `https://my-app.herokuapp.com/send` : "http://localhost:3001/send"; // 生产环境可注释该日志,调试时确认请求地址是否正确 console.log('当前请求地址', url) const res = await fetch(url, { method: "POST", headers: { "Content-type": "application/json", 'Accept': 'application/json' }, body: JSON.stringify({ formdata }), }) const resData = await res.json() if (resData.status === "success") { setMessage("Message Sent!"); } else { setMessage("Message failed to send"); } setFormdata({ name: "", email: "", subject: "", message: "", }); } catch (err) { console.error('请求错误', err) setMessage("Message failed to send"); } };
内容的提问来源于stack exchange,提问作者Ghalileo
相关产品推荐
相关产品推荐

