AJAX提交FormData联系表单后收到的邮件出现undefined值问题排查
问题根因
你前端提交的是FormData格式的数据,对应的请求头是multipart/form-data,但后端目前只配置了express.urlencoded()中间件,它只能解析application/x-www-form-urlencoded格式的请求体,所以无法解析出表单字段,req.body是空对象,解构出来的字段自然都是undefined。
两种解决方案
方案1:调整前端提交格式,适配现有后端配置
把FormData转成URLSearchParams格式提交,无需修改后端代码,修改前端send函数即可:
function send(event){ event.preventDefault(); const url = "https://us-central1-selexin-website.cloudfunctions.net/app/sendemail"; let form = document.querySelector('form'); let formData = new FormData(form); // 新增:把FormData转成urlencoded格式 const searchParams = new URLSearchParams(); for (const [key, value] of formData) { searchParams.append(key, value); } const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if(xhr.readyState === XMLHttpRequest.DONE){ console.log(formData) // Make a pop up message in green below the textarea box to notify user email was sent. } } xhr.open('POST', url, true); // 提交转好的格式而非原formData xhr.send(searchParams); };
方案2:后端新增解析中间件,适配前端现有提交逻辑
使用multer中间件解析FormData格式,你没有上传文件的需求,用multer().none()配置即可:
- 先安装依赖:
npm install multer - 修改后端代码:
const multer = require('multer'); const transport = nodemailer.createTransport(sendgridTransport({ auth: { api_key: apiKey }, })); app.use(express.urlencoded({extended: false})); app.use(cors({ origin: true })); // 新增:解析不带文件的FormData请求 app.use(multer().none()); app.post('/sendemail', (req, res) => { const {name, email, number, message} = req.body; return transport.sendMail({ to: 'email receiving', from: 'from this email', subject: 'New Contact Request', html: ` <p>You have a new Contact Request</p> <h3>Contact Details</h3> <ul> <li>Name: ${name}</li> <li>Email: ${email}</li> <li>Number: ${number}</li> <li>Message: ${message}</li> </ul> ` }).then(() => { res.sendStatus(200); console.log('it logs'); }) }); exports.app=functions.https.onRequest(app);
额外检查点
确认表单内所有输入框(对应name、email、number、message的input/textarea)都设置了正确的name属性,属性值要和后端解构的字段名完全一致,否则就算格式匹配也拿不到对应值。
内容的提问来源于stack exchange,提问作者LM17
相关产品推荐
相关产品推荐

