smtp.js 是一个可以直接在浏览器端调用的邮件发送库,它封装了 EmailJS 提供的 HTTP 接口,前端开发者不需要自建后端就能把表单内容发送到指定邮箱。不过在使用过程中,一个高频出现的报错让很多人头疼:页面弹出或者控制台打印出“电子邮件地址格式不正确”(英文环境为 The email address is not in a valid format 之类的提示)。这个错误信息本身比较笼统,收件人、发件人、回信地址任何一个字段不合规都会触发,所以不能只盯着一个输入框看。本文将从错误产生的机制讲起,逐个分析常见的触发场景,并给出对应的修复代码。

一、错误产生的原因分析
smtp.js 在调用 EmailJS 的 REST 接口之前,会对传入的几个关键参数做基本校验,其中就包括邮箱格式检查。一旦校验失败,它会直接以错误字符串的形式返回,而不是抛出异常,这也是很多新手容易忽略的地方:Email.send() 返回的是 Promise,错误信息出现在 then 的回调里,如果不写 catch 或者不打印返回值,就完全看不到报错内容。
触发这个错误最常见的场景有以下几类。第一类是用户在输入框中不小心输入了前后空格或者全角字符,比如把 @ 符号打成了全角的@,肉眼几乎看不出区别,但正则校验一定不通过。第二类是发件人地址(From 参数)配置错误,smtp.js 要求 From 必须是一个格式合法的邮箱,而且这个邮箱最好与你在 EmailJS 后台绑定的账号一致,否则即使格式正确也可能被拒绝。第三类是从表单取值时方式不对,例如用 innerText 取值带入了换行符,或者复用了被污染的变量,导致拼接出来的字符串里夹带了看不见的换行与制表符。
还有一类比较隐蔽的情况:代码里写了多个收件人,用逗号拼接,但 smtp.js 对批量收件人的格式有要求,地址之间不能有空格,写成 a@ipipp.com, b@ipipp.com 就会失败,必须写成 a@ipipp.com,b@ipipp.com。此外,如果 Subject 或 Body 中包含了从地址栏带过来的特殊字符,也可能干扰整体请求的解析,间接表现为邮箱格式错误。
二、前端预校验与字符串清洗
解决问题的关键一步是在提交前对邮箱做清洗和预校验。清洗是指去掉首尾空白、把全角字符替换成半角;预校验是指用正则表达式提前拦截明显不合法的输入,避免把脏数据发给 smtp.js。下面给出一段完整的校验函数,可以直接放进项目里使用。
// 清洗并校验邮箱地址
function cleanEmail(raw) {
if (typeof raw !== 'string') return '';
return raw
.trim() // 去掉首尾空格
.replace(/@/g, '@') // 全角@转半角
.replace(/./g, '.') // 全角点转半角
.replace(/\s+/g, ''); // 去掉中间所有空白字符
}
function isValidEmail(email) {
// 常规邮箱正则:字母数字开头,允许点、下划线、中划线
const reg = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
return reg.test(email);
}
// 使用示例
const input = document.querySelector('#email').value;
const email = cleanEmail(input);
if (!isValidEmail(email)) {
alert('请输入正确的邮箱地址');
return;
}
这段代码处理了三个高频问题:空格、全角字符和换行符。特别提醒一点,如果输入框是 textarea 或者值来自复制粘贴,字符串两端很可能带着看不见的 \n,trim() 只能处理首尾的标准空白,中间夹杂的空白则由 \s+ 的全局替换兜底。经过清洗和校验后,绝大多数格式类报错都能在提交前被拦截。
三、Email.send 的正确写法
校验通过之后,还需要保证 Email.send() 的参数写法正确。smtp.js 支持两种传参方式:一种是老的对象参数式,一种是链式调用式。无论哪种,From、To、Subject、Body 四个字段都不能为空,且 From 和 To 必须是通过校验的邮箱字符串。推荐使用 SecureToken 来避免在代码里暴露 SMTP 账号密码,这也是官方文档反复强调的安全实践。
Email.send({
SecureToken: "你的安全令牌", // 从 smtpjs.com 后台生成
To: "receiver@ipipp.com", // 多个收件人用逗号分隔,不要加空格
From: "sender@ipipp.com", // 必须与SecureToken绑定的邮箱一致
Subject: "用户反馈",
Body: "用户 " + name + " 提交了反馈:" + message
}).then(function (message) {
if (message === "OK") {
alert("邮件发送成功");
} else {
console.error("发送失败:" + message);
}
}).catch(function (err) {
console.error("请求异常:", err);
});
注意几个细节。第一,SecureToken 是在 smtpjs.com 网站上通过加密 SMTP 凭证生成的字符串,使用它之后就不再需要写 Host、Username、Password 这三个字段,代码更安全也更简洁。第二,From 字段的邮箱必须和生成 SecureToken 时绑定的账号一致,否则服务端会判定发件人不合法,错误信息也可能被误导性地显示为格式问题。第三,一定要在 then 回调里判断返回值是否为字符串 OK,因为 smtp.js 即使发送失败也走的是 then 而不是 catch,漏掉这个判断会让你误以为发送成功。
四、完整示例与排查清单
把前面的清洗、校验、发送串起来,就是一个可用的完整流程。为了便于快速定位问题,建议在开发阶段把清洗后的字符串打印到控制台,肉眼确认没有异常字符后再提交。
<input type="email" id="email" placeholder="收件邮箱">
<textarea id="msg" placeholder="邮件内容"></textarea>
<button onclick="sendMail()">发送</button>
<script src="https://smtpjs.com/v3/smtp.js"></script>
<script>
function sendMail() {
var to = cleanEmail(document.getElementById('email').value);
var msg = document.getElementById('msg').value;
if (!isValidEmail(to)) {
alert('收件邮箱格式不正确,请检查后重试');
return;
}
Email.send({
SecureToken: "你的安全令牌",
To: to,
From: "sender@ipipp.com",
Subject: "网站留言",
Body: msg
}).then(function (r) {
alert(r === "OK" ? "发送成功" : "发送失败:" + r);
});
}
</script>
如果按上述方式处理后仍然报格式错误,可以按照这份清单逐项排查:确认 From 与 SecureToken 绑定邮箱一致;确认多个收件人之间用英文逗号分隔且没有空格;确认取值用的是 value 而不是 innerText;确认没有把 Subject 等其他字段的值误传到 To 参数里;确认输入法没有输入全角字符。逐项对照下来,基本都能找到问题根源。另外要说明的是,纯前端发送邮件本质上把凭证暴露在浏览器中,生产环境更稳妥的做法是自建后端代理或使用云函数中转,smtp.js 更适合内部工具、演示页面这类对安全性要求不高的场景。