Nodemailer+Handlebars引入styles.css报错getaddrinfo ENOTFOUND
Nodemailer + Handlebars 引入CSS报错
getaddrinfo ENOTFOUND styles.css 的解决办法 问题原因
直接用<link rel='stylesheet' href='styles.css'>引入本地CSS在邮件场景下完全行不通——邮件客户端不会像浏览器那样读取你本地/服务器上的CSS文件,它会把styles.css当作一个域名去发起网络请求,自然会触发域名解析失败的错误。
解决办法
方案1:手动内联CSS(适合简单样式)
把styles.css里的所有样式直接复制到Handlebars模板的<style>标签中,或者直接给HTML元素添加style属性:
修改account-creation.hbs:
<style> /* 复制styles.css里的所有样式到这里 */ body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; background: #f6f6f6; color: #333; } .email-card { max-width: 600px; margin: 20px auto; padding: 20px; background: #fff; border-radius: 8px; } /* 其他样式... */ </style> <div class="email-card"> <h2>欢迎加入,{{name}}!</h2> <p>你的账户已成功创建,现在可以开始使用我们的服务了。</p> </div>
方案2:用工具自动内联CSS(适合复杂样式,推荐)
借助juice工具自动把外部CSS内联到HTML中,避免手动复制的麻烦:
- 先安装依赖:
npm install juice
- 修改发送邮件的逻辑,先读取模板和CSS,处理后再发送:
import * as fs from 'fs'; import * as path from 'path'; import * as juice from 'juice'; import * as handlebars from 'handlebars'; async accountCreation(name: string, email: string): Promise<void> { // 读取模板和CSS文件路径 const templateDir = path.join(__dirname, '../../public/account-creation'); const templateContent = fs.readFileSync(`${templateDir}/account-creation.hbs`, 'utf8'); const cssContent = fs.readFileSync(`${templateDir}/styles.css`, 'utf8'); // 编译Handlebars模板 const compiledTemplate = handlebars.compile(templateContent); let html = compiledTemplate({ name }); // 自动内联CSS html = juice.inlineContent(html, cssContent); // 发送邮件 await this.mailerService.sendMail({ to: email, subject: '本地环境账户创建通知', html: html, // 传入处理好的内联样式HTML }); console.log(`邮件已发送给 ${name} <${email}>`); }
方案3:Data URI引入(兼容性一般,不推荐)
把CSS内容转成Data URI写在<link>里,这种方式部分邮件客户端可能不支持,谨慎使用:
<link rel="stylesheet" href="data:text/css;charset=utf-8,body%20%7B%0A%20%20font-family%3A%20Arial%2C%20sans-serif%3B%0A%20%20background%3A%20%23f5f5f5%3B%0A%7D">
(注:需要把CSS内容URL编码后再填入)
内容的提问来源于stack exchange,提问作者Mujtaba Shafiq
相关产品推荐
相关产品推荐

