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

使用Node.js的Nodemailer发送邮件时仅显示纯文本、CSS样式未渲染的技术问题咨询

解决Nodemailer结合EJS发送邮件时CSS样式不渲染、仅显示纯文本的问题

我帮你排查了代码里的几个关键问题,这应该就是导致邮件样式不生效、只显示纯文本的原因,咱们一步步来修复:

首先看代码里的明显错误

  1. 变量拼写失误:你写的tranporter transporter.sendMail是重复且拼写错误的,正确的应该是transporter.sendMail——这个错误会直接导致邮件发送逻辑异常,甚至根本没正确传递HTML内容。
  2. 异步逻辑混乱:你用了await却又嵌套了回调函数,这会让EJS的渲染结果无法正确传递给mainOptions的html字段,最终可能发送的是空或者未渲染的内容。
  3. 缺失transporter实例创建:你的代码里没看到创建transporter的部分,这是Nodemailer发送邮件的核心前提,没有它根本没法正常发邮件。

修复后的完整代码

咱们把这些问题都修正,改用async/await处理异步逻辑,让代码更清晰:

import express from 'express'
import Email from "../Model/email.js"
import nodemailer from "nodemailer"
import ejs from "ejs"

// 第一步:创建正确的transporter实例(以Gmail为例,其他邮箱类似)
const transporter = nodemailer.createTransport({
  service: 'Gmail',
  auth: {
    user: 'example@gmail.com', // 你的发件邮箱
    pass: 'your-app-specific-password' // 注意:Gmail需要用应用专用密码,不是登录密码!
  }
});

// 用async函数封装发送逻辑,避免回调嵌套
async function sendStyledEmail() {
  try {
    // 正确渲染EJS模板,用await代替回调
    const rawHtml = await ejs.renderFile("views/mail.ejs", { name: 'Stranger' });
    
    const emailOptions = {
      from: 'example@gmail.com',
      to: 'a@gmail.com',
      subject: 'Hello',
      html: rawHtml // 确保这里传递的是渲染后的完整HTML字符串
    };

    const sendResult = await transporter.sendMail(emailOptions);
    console.log('邮件发送成功:', sendResult.response);
  } catch (error) {
    console.error('发送邮件出错:', error);
  }
}

// 调用发送函数
sendStyledEmail();

关键:邮件样式必须用内联CSS

就算前面的代码都修复了,很多邮件客户端(比如Gmail、Outlook)不支持<style>标签里的样式,必须用内联CSS才能正常渲染。

手动写内联样式(推荐简单场景)

修改你的views/mail.ejs,把样式直接写在HTML元素的style属性里:

<!-- views/mail.ejs 示例 -->
<div style="background-color: #f5f5f5; padding: 20px; border-radius: 8px;">
  <h1 style="color: #2c3e50; font-family: Arial, sans-serif; margin-top: 0;">Hello <%= name %>!</h1>
  <p style="color: #34495e; font-size: 16px; line-height: 1.6;">这是一封带有正确样式的测试邮件,现在应该能正常显示啦😉</p>
</div>

自动转换内联样式(复杂场景)

如果你的模板样式很多,不想手动写内联,可以用juice库自动转换:

  1. 先安装依赖:
npm install juice
  1. 在代码里添加样式处理:
import juice from 'juice';

// ...其他代码不变
const rawHtml = await ejs.renderFile("views/mail.ejs", { name: 'Stranger' });
// 自动把<style>里的样式转成内联CSS
const styledHtml = juice(rawHtml);

const emailOptions = {
  // ...其他配置
  html: styledHtml // 传递处理后的HTML
};

最后再检查这几点

  • 确认你的邮箱开启了SMTP服务,比如Gmail需要开启两步验证后生成应用专用密码,不能用普通登录密码。
  • 测试时可以用邮件测试工具(比如Mailtrap)先预览,避免频繁发送到真实邮箱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:57:49