页面加载时POST请求自动触发,联系表单邮件发送失败
单页网站联系表单邮件发送异常问题
我的单页网站内置邮件联系表单,需求是用户填写提交表单时给我的账号发送邮件,但功能失效:页面加载完成后会立即触发POST请求,导致app.js里的邮件发送函数因参数未定义无法处理请求。

相关代码
app.js中的Node.js邮件发送函数
const app = require('express')(); const nodemailer = require('nodemailer'); const path = require('path'); const PORT = process.env.PORT || 3000; const express = require('express'); async function mainMail(name, email, message) { const transporter = await nodemailer.createTransport({ service: 'gmail', auth: { user: '*my_email*', pass: '*my_password*' } }); const mailOption = { from: '*my email*', to: '*my second email*', subject: email, html: `You've got message from: email: ${email} name: ${name} message: ${message}` }; try { await transporter.sendMail(mailOption); return Promise.resolve('Message sent successfully'); } catch(error) { return Promise.reject(error); } } app.post('/', async(req, res, next) => { try { await mainMail(req.body.name, req.body.email, req.body.message); res.send('Message sent!'); } catch(error) { console.log(error); res.send('Message not sent!'); } }) app.listen(PORT, () => { console.log(`PORT -> ${PORT}`); });
HTML表单代码
<form method="post" class="contacts-form" id="contacts-form"> <div class="contacts-upper-inputs"> <div class="input-container half-input"> <label for="name" class="primary-label">Name</label> <input required name="name" id="name" class="primary-input"></input> </div> <div class="input-container half-input"> <label for="email" class="primary-label">Email</label> <input required name="email" id="email" class="primary-input"></input> </div> </div> <div class="input-container"> <label for="message-text" class="primary-label">Message</label> <textarea required name="message" name="" id="message" cols="30" rows="10" class="primary-input"></textarea> </div> <div style="display: flex; justify-content: center;"> <button onclick="sendEmail(event)" class="btn-contact">Submit</button> </div> </form>
index.js中的提交处理函数
function sendEmail(event) { event.preventDefault(); const name = document.getElementById('name').value; const email = document.getElementById('email').value; const message = document.getElementById('message').value; $.post('/', { name: name, email: email, message: message }, function(data, status) { console.log('status -> ', status); }); }
问题原因及修复方案
核心问题
- Express未配置请求体解析中间件:没有添加
express.urlencoded()或express.json(),导致req.body无法读取表单提交的数据,触发参数未定义错误。 - 表单按钮默认行为冲突:按钮默认类型为
submit,即使有onclick事件,仍可能触发表单默认POST提交,导致页面加载时或点击时重复发起请求。 - 单页网站静态资源未配置:Express未处理GET请求返回主页,可能导致路由逻辑混乱,触发意外的POST请求。
修复步骤
- 添加请求体解析中间件:在app.js的POST路由定义前加入以下代码,让Express能解析表单数据:
app.use(express.urlencoded({ extended: true })); app.use(express.json()); // 可选,支持JSON格式请求体
- 修改按钮类型避免默认提交:将HTML中的按钮明确设置为
button类型,彻底阻止表单默认提交行为:
<button type="button" onclick="sendEmail(event)" class="btn-contact">Submit</button>
- 配置静态文件服务与GET路由:为单页网站添加静态资源服务,并处理根路径的GET请求返回主页:
// 假设静态文件(HTML/CSS/JS)放在项目根目录的public文件夹下 app.use(express.static(path.join(__dirname, 'public'))); // 处理GET请求返回主页 app.get('/', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'index.html')); });
内容的提问来源于stack exchange,提问作者Nkwitchoua
相关产品推荐
相关产品推荐

