使用Express+Nodemailer发邮件时遇空响应及请求挂起问题求助
Nodemailer请求无响应错误分析与修复
问题现象
- 浏览器发起POST请求
/contact时,出现net::ERR_EMPTY_RESPONSE和TypeError: Failed to fetch错误 - 添加
sendEmail函数后,请求一直处于pending状态 - Postman测试该路由时,返回DNS超时错误:
Error: Error: queryA ETIMEOUT gmail at QueryReqWrap.onresolve [as oncomplete] (node:dns:213:19) { errno: undefined, code: 'EDNS', syscall: 'queryA', hostname: 'gmail', command: 'CONN' }
核心错误点
- SMTP主机配置错误:Nodemailer中设置
host: "gmail"是无效域名,Gmail官方SMTP主机地址为smtp.gmail.com - 响应对象未传递:
sendEmail函数尝试使用res.send(),但res并未作为参数传入,导致Express无法结束请求,造成客户端请求一直pending
修复步骤
1. 修正Nodemailer传输配置
将SMTP主机改为smtp.gmail.com,并补充正确的端口和TLS配置:
const transporter = nodemailer.createTransport({ host: "smtp.gmail.com", port: 587, secure: false, // 587端口用false,465端口用true requireTLS: true, auth: { user: process.env.EMAIL, pass: process.env.PASS3 } });
2. 传递响应对象到sendEmail函数
修改POST路由,将res传入sendEmail:
router.post("/contact", (req, res)=>{ console.log("req.body: ", req.body) const contents = req.body if(!contents){ return res.status(400).send({status: "failed"}); } sendEmail(contents, res) // 传入res对象 });
同时更新sendEmail函数的参数:
function sendEmail(obj, res){ // 接收res参数 const transporter = nodemailer.createTransport({ host: "smtp.gmail.com", port: 587, secure: false, requireTLS: true, auth: { user: process.env.EMAIL, pass: process.env.PASS3 } }); const info = { from: process.env.EMAIL, to: process.env.EMAIL2, subject: `Message from ${obj.nameUser} <${obj.email}>: ${obj.subject}`, text: obj.message }; transporter.sendMail(info,(err, emailInfo)=>{ if(err){ console.log("Error: ", err); res.status(500).send('error'); // 正确返回错误响应 }else{ console.log('Email sent ' + emailInfo.response); res.status(200).send('success'); // 正确返回成功响应 } }); }
3. 验证环境变量
确保.env文件中的EMAIL、EMAIL2、PASS3(应用专用密码)配置正确,且Gmail账户已开启SMTP访问权限。
修正后效果
- 客户端请求不再pending,能收到明确的成功/失败响应
- Nodemailer能正确连接Gmail SMTP服务器发送邮件
- 浏览器不再出现
ERR_EMPTY_RESPONSE和Failed to fetch错误
内容的提问来源于stack exchange,提问作者NeophyteLou
相关产品推荐
相关产品推荐

