使用Netlify Functions发送Gmail时表单参数显示Undefined的问题求助
解决Lambda函数接收Vue表单数据后邮件字段显示undefined的问题
嘿,我帮你排查出几个核心问题,咱们一步步来修复:
1. 最直接的错误:调用sendMail时未传递参数
你定义的sendMail函数需要接收name、email、phone、message四个参数,但调用的时候直接写了sendMail(),完全没传值——这必然会导致函数内部的参数都是undefined。
修改这一行:
// 原代码 sendMail(); // 修改后 sendMail(name, email, phone, message);
2. 表单数据解析方式与前端发送格式不匹配
这是导致字段解析失败的关键原因:你用了qs.parse(event.body),但这个方法是用来解析application/x-www-form-urlencoded格式的表单数据(传统HTML表单默认格式),而Vue前端通常会用axios或fetch发送JSON格式的数据(Content-Type: application/json),这时候event.body是JSON字符串,应该用JSON.parse解析。
针对不同发送格式的修复:
如果前端发送的是JSON数据(推荐方式),替换解析代码:
// 原代码 const { name, email, phone, message } = qs.parse(event.body); // 修改后 const { name, email, phone, message } = JSON.parse(event.body);如果你不确定前端的发送格式,可以加个兼容判断:
let body; // 检查请求头的Content-Type if (event.headers['Content-Type']?.includes('application/json')) { body = JSON.parse(event.body); } else { body = qs.parse(event.body); } const { name, email, phone, message } = body;
3. 异步邮件发送未等待完成(隐性问题)
现在你的代码调用sendMail后立刻执行callback返回响应,但nodemailer.sendMail是异步操作——Lambda可能在邮件发送完成前就终止进程,虽然你说邮件能发送,但这种写法不稳定,极端情况下会出现发送失败的情况。
修复方式(二选一):
方式一:把callback放在sendMail的回调里
transporter.sendMail(mailOptions, function (err, info) { if (err) { console.log(err); // 发送失败返回500状态码 callback(null, { statusCode: 500, body: "Erreur lors de l'envoi du mail !" }); } else { console.log(info); // 发送成功返回200 callback(null, { statusCode: 200, body: "Merci !" }); } });
方式二:改用async/await(代码更清晰)
把handler改成异步函数,等待邮件发送完成后再返回响应:
const nodemailer = require('nodemailer'); const qs = require("querystring"); // 改成async函数 exports.handler = async function (event, context) { try { let body; if (event.headers['Content-Type']?.includes('application/json')) { body = JSON.parse(event.body); } else { body = qs.parse(event.body); } const { name, email, phone, message } = body; const transporter = nodemailer.createTransport({ service: "gmail", auth: { user: "xxxxxx@gmail.com", pass: "xxxxxxx" // 注意:这里需要用Gmail的应用专用密码 } }); const mailOptions = { from: email, to: "xxxxxxx@gmail.com", subject: `Message from ${name} to FoodAllergyFriendly website`, html: `${name} avec l'adresse ${email} et le numéro de téléphone ${phone} a écrit ceci: <br> <p>${message}</p>` }; // 等待邮件发送完成 await transporter.sendMail(mailOptions); return { statusCode: 200, body: "Merci !" }; } catch (err) { console.log(err); return { statusCode: 500, body: "Erreur lors de l'envoi du mail !" }; } }
额外提醒:Gmail登录权限问题
现在Gmail默认禁止普通密码登录第三方应用,你需要先给Google账号开启两步验证,然后生成一个应用专用密码,替换代码里的pass字段,否则会出现登录失败的错误。
内容的提问来源于stack exchange,提问作者yoyojs
相关产品推荐
相关产品推荐

