在Next.js中调用自定义SendMail接口时出现404错误的技术求助
问题描述
调用Sendmail.ts接口时触发404错误:
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (sendMail, line 0)
自行基于Next.js + nodemailer实现邮件发送接口,尝试将api文件夹放置在app、src等目录下均未解决问题,以下是前后端代码:
前端提交代码
const handleSubmitForm = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 发送数据到服务器 const response = await fetch('/api/sendMail', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ senderEmail: formInputs.email, name: formInputs.name, message: formInputs.message, floortype: selectedFloor, postcode: formInputs.postcode, location: formInputs.location, }), }); if (response.ok) { // 处理成功发送 console.log('邮件成功发送!'); } else { // 处理发送错误 console.error('发送邮件时出错'); } }
后端接口代码
const transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: 'romanenkofloors@gmail.com', pass: '**********', } }); export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method === 'POST') { const { senderEmail, name, message, floortype, postcode, location }: MailData = req.body; // 邮件内容 const mailOptions = { from: senderEmail, to: 'romanenkofloors@gmail.com', subject: '新访客请求', text: `姓名: ${name}\n邮箱: ${senderEmail}\n邮政编码: ${postcode}\n城市: ${location}\n期望地板类型: ${floortype}\n问题: ${message}`, }; try { await transporter.sendMail(mailOptions); res.status(200).json({ success: true }); } catch (error) { console.error(error); res.status(500).json({ success: false, error: '发送邮件时出错' }); } } else { res.status(405).end(); } }
排查与解决步骤
1. 匹配Next.js版本的路由规则
Next.js 13+ App Router:API路由必须遵循
app/api/[路由名]/route.ts结构,请求路径/api/sendMail对应的目录结构应为:app/ api/ sendMail/ route.ts同时需修改接口代码,导出
POST函数而非默认handler:import nodemailer from 'nodemailer'; const transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: 'romanenkofloors@gmail.com', pass: '**********', } }); export async function POST(req: Request) { const { senderEmail, name, message, floortype, postcode, location } = await req.json(); const mailOptions = { from: senderEmail, to: 'romanenkofloors@gmail.com', subject: '新访客请求', text: `姓名: ${name}\n邮箱: ${senderEmail}\n邮政编码: ${postcode}\n城市: ${location}\n期望地板类型: ${floortype}\n问题: ${message}`, }; try { await transporter.sendMail(mailOptions); return new Response(JSON.stringify({ success: true }), { status: 200 }); } catch (error) { console.error(error); return new Response(JSON.stringify({ success: false, error: '发送邮件时出错' }), { status: 500 }); } }Next.js 12及以下 Pages Router:API路由需放在
pages/api/sendMail.ts,确保文件名与请求路径完全匹配(注意大小写)。
2. 检查文件名与路径大小写
Linux/macOS环境下文件名区分大小写,请求路径/api/sendMail对应的文件名必须是sendMail.ts,不能是SendMail.ts或其他大小写组合。
3. 重启开发服务器
修改API路由文件或目录结构后,必须重启Next.js开发服务器,否则新路由不会生效。
4. 验证接口可用性
直接用Postman或浏览器发起POST请求到http://localhost:3000/api/sendMail,若返回405(Method Not Allowed)说明接口存在;若仍返回404,需重新检查路由结构。
5. 适配src目录结构
如果项目使用src目录:
- Pages Router:
src/pages/api/sendMail.ts - App Router:
src/app/api/sendMail/route.ts
6. Gmail授权额外注意
即使接口正常,Gmail可能因安全设置阻止发送,建议:
- 临时测试可开启低安全性应用访问(不推荐生产环境)
- 生产环境使用应用专用密码(需先开启2FA)
内容的提问来源于stack exchange,提问作者Володимир Романенко

