You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Nodemailer发送外部HTML文件替代JS内嵌HTML代码?

Nodemailer 引用外部HTML文件发送邮件实现方案

你可以通过两种方式实现需求,无需在JS文件中内嵌大段HTML代码:

方案1:原生Node.js实现(无额外依赖)

不需要安装第三方包,直接用Node内置模块即可完成:

  • 第一步:拆分独立模板文件
    在项目中新建模板存放目录,比如templates,将原来内嵌的HTML代码单独存为resetPasswordEmail.html,动态内容用自定义占位符标记:
    <!-- templates/resetPasswordEmail.html -->
    <html>
    <head>
        <meta charset="utf-8" />
        <style>
            body, * {
                direction: ltr;
            }
        </style>
    </head>
    <body>
        <h1>You've requested a password reset!</h1>
        <h3>
            Click this <a href="{{RESET_LINK}}">Link</a> to set a new password.
        </h3>
    <body>
    </html>
    
  • 第二步:修改业务代码,读取模板替换动态内容
    引入Node内置的文件系统和路径处理模块,读取外部HTML文件后替换占位符,再传入mailOptions即可:
    // 文件顶部引入内置模块
    const fs = require('fs/promises');
    const path = require('path');
    
    // 原有业务逻辑修改
    .then(async user => {
        // 拼接模板文件绝对路径,避免相对路径读取失败
        const templatePath = path.resolve(__dirname, 'templates', 'resetPasswordEmail.html');
        let htmlContent = await fs.readFile(templatePath, 'utf-8');
        
        // 替换模板中的动态占位符
        const resetLink = `http://localhost:8000/new-password/${token}`;
        htmlContent = htmlContent.replace('{{RESET_LINK}}', resetLink);
    
        const mailOptions = {
            from: "Mohammad.front.dev@gmail.com",
            to: user.email,
            subject: "Reset Password",
            html: htmlContent
        };
    
        transporter.sendMail(mailOptions, (error, info) => {
            if(error) {
                console.log(error);
                req.flash("error", "重置邮件发送失败,请稍后重试");
            } else {
                console.log(info);
                req.flash("info", "请查收邮件中的密码重置链接");
            }
            res.redirect("/products");
        });
    })
    

    注:原代码先执行跳转再发邮件的逻辑存在体验问题,如果邮件发送失败用户无法收到错误提示,建议将响应逻辑放到邮件发送回调中处理。


方案2:使用模板引擎实现(适合多动态变量场景)

如果邮件模板中动态内容较多,手动替换占位符维护成本高,可以用模板引擎渲染,以常用的EJS为例:

  • 安装依赖
    npm install ejs
    
  • 编写EJS格式模板,将动态内容用EJS语法标记,存为templates/resetPasswordEmail.ejs,只需要把原HTML中的占位符{{RESET_LINK}}替换为<%= resetLink %>即可。
  • 调用渲染方法传入参数生成最终HTML:
    const ejs = require('ejs');
    const path = require('path');
    
    .then(async user => {
        const templatePath = path.resolve(__dirname, 'templates', 'resetPasswordEmail.ejs');
        // 直接传入动态参数渲染模板
        const htmlContent = await ejs.renderFile(templatePath, {
            resetLink: `http://localhost:8000/new-password/${token}`
        });
    
        const mailOptions = {
            from: "Mohammad.front.dev@gmail.com",
            to: user.email,
            subject: "Reset Password",
            html: htmlContent
        };
    
        // 后续邮件发送、响应逻辑和方案1一致
        transporter.sendMail(mailOptions, (error, info) => {
            // 错误处理、消息提示、跳转
        });
    })
    

注意事项

  • 读取模板文件时不要直接写相对路径,必须用path.resolve结合__dirname拼接绝对路径,避免启动目录变化、部署时出现文件找不到的问题
  • 生产环境可以在服务启动时一次性读取模板文件缓存到内存中,不需要每次请求都读磁盘,提升响应速度
  • 多数邮箱客户端对head标签内的CSS兼容性较差,正式发送的通知邮件建议把样式写成内联形式,避免样式丢失

内容的提问来源于stack exchange,提问作者MORA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:45:43