Next.js集成SendGrid发件成功但收件箱无邮件,API响应异常求助
Next.js + SendGrid 联系表单问题排查与修复
一、修复API响应未返回的终端错误
终端提示的API resolved without sending a response for /api/contact, this may result in stalled requests.是因为API路由未正确向客户端返回响应,且异步发送操作未被等待。
问题根源
- 原API handler不是异步函数,无法等待SendGrid的异步发送流程完成
- 立即执行的async函数仅在catch分支返回了错误响应,成功分支未返回任何响应,导致Next.js判定请求未处理完成
修改后的API代码
import sgMail from "@sendgrid/mail"; // 将handler改为async函数,支持等待异步操作 export default async function handler(req, res) { if (req.method !== "POST") { return res.status(405).json({ message: "INVALID_METHOD" }); } const { name, email, subject, content } = req.body; // 处理换行和过滤非法HTML标签 const message = content .replace(/\n/g, "<br>") .replace(/\r/g, "<br>") .replace(/\t/g, "<br>") .replace(/<(?!br\s*\/?)[^>]+>/g, ""); sgMail.setApiKey(process.env.KEY_SENDGRID); const sendGridMail = { to: "arotiana4612@gmail.com", from: "kaspersky2mahanaima@gmail.com", subject: subject, templateId: "d-b48909edf062437e8442f861a4c8be29", dynamic_template_data: { name: name, email: email, subject: subject, content: message, }, }; try { const response = await sgMail.send(sendGridMail); console.log(response[0].statusCode); console.log(response[0].headers); // 成功时返回明确响应 return res.status(200).json({ message: "EMAIL_SENT_SUCCESS" }); } catch (err) { console.error(err); return res.status(500).json({ error: JSON.stringify(err), message: "ERROR_WITH_SENDGRID", }); } }
二、排查SendGrid返回202但收不到邮件的问题
SendGrid返回202仅表示邮件已被平台接受,不代表已成功送达收件箱,按以下步骤排查:
- 验证发件邮箱:SendGrid要求发件地址必须经过单发件人或域名验证,未验证的地址发送的邮件会被收件服务商拦截。登录SendGrid后台,在「Sender Authentication」菜单完成验证。
- 检查垃圾邮件文件夹:优先查看收件箱的垃圾邮件、促销邮件分类文件夹,测试邮件常被归类到此处。
- 查看SendGrid邮件活动日志:登录后台「Email Activity」页面,查看邮件状态:
- 显示「Delivered」:说明邮件已送达,需检查收件箱分类文件夹
- 显示「Bounced」:根据退回原因处理(如收件邮箱不存在、邮箱容量不足)
- 显示「Spam Reported」:邮件被标记为垃圾邮件,需优化邮件内容或提升发件域名信誉
- 确认模板变量匹配:检查SendGrid模板中的动态变量(如
{{name}}、{{content}})是否与代码中dynamic_template_data的key完全一致,变量不匹配会导致邮件内容异常。 - 检查发件域名信誉:若发件域名是新注册或有过垃圾邮件记录,会被反垃圾系统拦截,可在SendGrid后台查看「Reputation」评分。
客户端代码优化(可选)
增加非JSON响应处理,避免解析失败:
const onSubmit: SubmitHandler<Inputs> = async (formData) => { if (!isLoading) { setIsLoading(true); try { const response = await fetch("/api/contact", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(formData), }); let result; try { result = await response.json(); } catch (e) { result = { message: "服务器返回无效响应" }; } if (!response.ok) { console.log("发送邮件失败:", result); } else { console.log("邮件发送成功"); } return result; } catch (err) { console.log("网络错误:", err); return { message: "网络请求失败" }; } finally { setIsLoading(false); } } };
内容的提问来源于stack exchange,提问作者Aro
相关产品推荐
相关产品推荐

