编程 Express 注册表单的邮件验证中间件:从内联校验到 MX 检查

2026-09-08 02:10:01

Express 注册表单的邮件验证中间件:从内联校验到 MX 检查

注册表单看起来简单,真跑在生产就露馅:同一份邮件检查逻辑被复制粘贴到每个创建用户的路径——注册、邀请好友、管理员加人——六个月后有人新增 "invite teammate" 接口,整个检查就忘了,因为它没有任何集中强制的地方,只是每个人都要记住的"约定"。

第一步:把校验抽成中间件

Express 中间件是自然解法:定义一次,挂到需要的路由上。

// middleware/verifyEmail.js
function isValidFormat(email) {
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return regex.test(email);
}

async function verifyEmailMiddleware(req, res, next) {
  const { email } = req.body;
  if (!email || !isValidFormat(email)) {
    return res.status(400).json({ error: 'Please provide a valid email address' });
  }
  next();
}

第二步:格式之外——MX 记录检查

只查格式拦不住 test@test.com 或根本不收邮件的域名。next() 之前做异步查询:

const dns = require('dns').promises;

async function verifyEmailMiddleware(req, res, next) {
  const { email } = req.body;
  if (!email || !isValidFormat(email)) return res.status(400).json({ error: '...' });

  const domain = email.split('@')[1];
  try {
    const mxRecords = await dns.resolveMx(domain);
    if (mxRecords.length === 0) {
      return res.status(400).json({ error: 'This domain cannot receive email' });
    }
  } catch {
    return res.status(400).json({ error: 'This domain cannot receive email' });
  }
  next();
}

第三步:超时与失败要优雅处理

DNS 查询可能因与用户邮箱无关的原因挂起或失败(网络抖动、DNS 服务器超时)。如果中间件把每个失败都当"非法邮箱",会拒绝真实用户——需要区分"域名确定不收信"与"查询暂时失败",前者拒绝,后者放行或降级。

实践建议

  • 集中式中间件比内联校验可靠:新路由默认获得检查,不再依赖记忆;
  • 格式校验 + MX 查询分层,先挡垃圾输入再挡假域名;
  • DNS 失败不等于邮箱非法,超时/失败路径要单独处理,别误伤真实用户。

来源:Building an Email Verification Middleware for Express.js Signup Forms - DEV Community

复制全文 生成海报 Express Node.js 中间件 教程

推荐文章

程序员茄子在线接单