Nodemailer本地运行正常 部署上线后无法发送邮件问题求助
Nodemailer部署后无法发送邮件解决方案
代码问题排查修正
- 发件人地址不完整:当前配置的
user: "subrata@spineor"、from: "subrata@spineor"均缺失域名后缀,需补全为完整邮箱地址(例:subrata@spineor.com),本地环境校验宽松未报错,服务器严格校验会直接拒绝请求。 - SMTP加密规则缺失:587端口对应STARTTLS加密方式,需明确配置加密规则,避免服务器安全策略拦截请求。
- 异步逻辑无响应:当前邮件发送为异步操作,未向接口返回响应,服务器可能提前销毁请求上下文导致发送中断。
- 参数顺序错误:原代码将接口参数
res和req写反,且第一个参数实际应为表单提交数据,需调整参数顺序。
服务器/邮箱侧限制排查
- 端口放行检查:大部分云服务商默认封禁25、587等邮件发送端口,需登录服务器安全组放开587端口的出方向访问规则,部分服务商需额外提交工单申请解封邮件端口。
- 邮箱安全限制检查:Outlook/live邮箱默认拦截陌生IP的登录请求,登录发件人邮箱的安全中心,将服务器IP加入信任列表;若邮箱开启了两步验证,需生成应用专用密码替换代码中的原登录密码。
修正后代码示例
const nodemailer = require('nodemailer'); // 调整为async函数支持异步等待 exports.sendMail = async function (formData, req, res) { console.log("In Mail Service", formData); try { const transporter = nodemailer.createTransport({ host: "smtp.live.com", port: 587, secure: false, // 587端口对应非加密连接,开启STARTTLS tls: { rejectUnauthorized: false // 忽略自签名证书错误,适配服务器环境 }, auth: { user: "subrata@spineor.com", // 补全完整邮箱地址 pass: "你的登录密码/应用专用密码", }, }); const mailOptions = { from: "subrata@spineor.com", // 补全完整发件人地址 to: "muskan@spineor.com", subject: "A New Client!", text: "welcome to Mailer ", html: `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Contacted us</title> <style> *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } table { border-collapse: collapse; box-shadow: 0 5px 10px #e1e5ee; text-align: left; overflow: hidden; width: 100%; } thead { box-shadow: 0 5px 10px #e1e5ee; } th { padding: .5rem 1rem; text-transform: uppercase; letter-spacing: 0.1rem; font-size: 0.7rem; font-weight: 900; } td { padding: .5rem 1rem; } a { text-decoration: none; color: #2962ff; } .status { border-radius: 0.2rem; background-color: red; padding: 0.2rem 1rem; text-align: center; } .status-pending { background-color: #fff0c2; color: #a68b00; } .status-paid { background-color: #c8e6c9; color: #388e3c; } .status-unpaid { background-color: #ffcdd2; color: #c62828; } .amount { text-align: right; } tr:nth-child(even) { background-color: #f4f6fb; } </style> </head> <body> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0"> <tbody> <tr> <td align="center"> <table class="col-600" width="600" border="0" align="center" cellpadding="0" cellspacing="0"> <tbody> <tr> <td align="center" valign="top" bgcolor="#66809b" style="background-size:cover; background-position:top;height:400px"> <table class="col-600" width="600" height="200" border="0" align="center" cellpadding="0" cellspacing="0"> <tbody> <tr> <td height="40"></td> </tr> <tr> <td height="50"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> <tr> <td align="center"> <table class="col-600" width="400" border="0" align="center" cellpadding="0" cellspacing="0" style="margin-left:20px; margin-right:20px;"> <tbody> <tr> <td align="center"> <table class="col-600" width="400" border="0" align="center" cellpadding="0" cellspacing="0" style=" border-left: 1px solid #dbd9d9; border-right: 1px solid #dbd9d9;"> <tbody> <tr> <td height="50"></td> </tr> <tr> <td align="center"> <table> <thead> <tr> <th>Name</th> <th>Email</th> <th>Phone</th> <th>Query</th> </tr> </thead> <tr> <td>${formData.name}</td> <td>${formData.email}</td> <td>${formData.phone}</td> <td>${formData.query}</td> </tr> </table> </td> </tr> <tr> <td height="50"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </body> </html>`, }; // 等待邮件发送完成再返回响应 const info = await transporter.sendMail(mailOptions); console.log("Email sent: " + info.response); // 可根据业务需求调整返回内容 return res.status(200).json({code:200, msg:"邮件发送成功"}); } catch (error) { console.log("mail send error", error); return res.status(500).json({code:500, msg:"邮件发送失败", error: error.message}); } };
内容的提问来源于stack exchange,提问作者Jaspreet
相关产品推荐
相关产品推荐

