
本文介绍如何将 mongodb 中存储的含占位符的 html 模板(如 `@payment - amount to pay`)动态替换为实际值,并最终提取为无标签、无换行、语义连贯的纯文本,适用于外部邮件 api 的正文发送。
在构建邮件通知系统时,常将可复用的 HTML 模板(支持占位符变量)存入 MongoDB,例如用于还款确认的模板。但直接将原始 HTML 作为邮件正文发送会导致收件人看到冗余标签(如
Dear Customer, An amount of Rs. 111 for your Loan Account Number 8204221103679 has been received on 24-Jul-2023 ,vide receipt no 1690195463903291. Payment Mode: Cash. Please find the receipt attached below.
实现该目标需两个关键步骤:变量替换 → HTML 转纯文本。推荐使用浏览器原生 DOMParser API(服务端可选用 jsdom 或 cheerio),兼顾安全性与兼容性。
✅ 步骤一:安全替换占位符变量
模板中所有 @Payment - XXX 均为语义化占位符,需映射为真实业务值。建议采用对象字面量 + 正则全局替换,避免 DOM 操作依赖(如 getElementById),提升可移植性:
const htmlTemplate = `Dear Customer,An amount of Rs. @Payment - Amount to Pay for your Loan Account Number @Payment - Loan Number has been received on @Payment - Date, vide receipt no @Payment - Receipt Number.Payment Mode: @Payment - Payment Mode.Please find the receipt attached below.`; const replacements = { "@Payment - Amount to Pay": "111", "@Payment - Loan Number": "8204221103679", "@Payment - Date": "24-Jul-2023", "@Payment - Receipt Number": "1690195463903291", "@Payment - Payment Mode": "Cash" }; let processedHtml = htmlTemplate; Object.entries(replacements).forEach(([placeholder, value]) => { // 使用 RegExp 构造函数确保特殊字符被正确转义(如括号、点号) const escapedPlaceholder = placeholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const regex = new RegExp(escapedPlaceholder, 'g'); processedHtml = processedHtml.replace(regex, value); });
⚠️ 注意:若占位符含正则元字符(如 @Payment - Amount (INR)),必须手动转义,否则 replace() 可能失效或报错。
✅ 步骤二:解析 HTML 并提取纯净文本
使用 DOMParser 将替换后的 HTML 字符串解析为文档对象,再通过 textContent 获取所有文本节点内容(自动忽略标签、脚本、样式),最后清理多余空白:
立即学习“前端免费学习笔记(深入)”;
const parser = new DOMParser(); const doc = parser.parseFromString(processedHtml, 'text/html'); let text = doc.body?.textContent || doc.documentElement?.textContent || ''; // 合并连续空白(含换行、制表、多空格)为单个空格,并修剪首尾 text = text.replace(/\s+/g, ' ').trim(); console.log(text); // 输出:Dear Customer, An amount of Rs. 111 for your Loan Account Number 8204221103679 has been received on 24-Jul-2023 ,vide receipt no 1690195463903291. Payment Mode: Cash. Please find the receipt attached below.
? 补充说明与最佳实践
-
服务端兼容性:Node.js 环境不支持 DOMParser,请使用 jsdom(模拟完整 DOM)或轻量级 cheerio(服务器端 jQuery-like 解析):
npm install jsdom
const { JSDOM } = require('jsdom'); const dom = new JSDOM(processedHtml); const text = dom.window.document.body.textContent.replace(/\s+/g, ' ').trim(); 安全性提示:此方案不执行脚本、不加载外部资源,DOMParser 仅做静态解析,天然防御 XSS;但若模板来源不可信,仍建议在入库前做基础 HTML 清洗(如移除
性能优化:对高频调用场景(如批量发信),可预编译正则表达式或缓存 DOMParser 实例,避免重复创建开销。
通过以上两步,即可稳定、安全地将富文本模板转化为符合邮件 API 要求的高质量纯文本正文,兼顾业务灵活性与终端用户体验。











