fs.readfile 显示html,在异步fs.readFile的回调中使用EJS呈现HTML模板?

博主在尝试将同步的fs.readFileSync替换为异步的fs.readFile以实现邮件发送过程中的HTML模板渲染。在回调中使用EJS渲染模板时遇到错误,提示模板对象没有indexOf方法。同步方式工作正常,但异步执行时模板解析失败。问题可能出在异步读取文件的内容处理上。

我用fs.readFileSync轻松实现了这一点,但我想异步执行此操作。我的代码如下。在异步fs.readFile的回调中使用EJS呈现HTML模板?

function send(err, str){

if(err){

console.log(err);

}

var template = ejs.render(str, 'utf8', {name: data.name});

transporter.sendMail({

from: myEmail,

to: anotherEmail,

subject: mySubject,

html: template,

attachments: images

}, function(err, response) {

if(err){

console.log(err);

}

});

}

fs.readFile('emailTemplate.ejs', send);

所以我做了我自己的fs.readFile回调,这样当该文件已被读取它将使电子邮件,把适当的名称,然后用nodemailer把它关闭。但是,它不喜欢这样。如果没有问题,它会通过错误获取,但在渲染模板时呈现以下错误。

TypeError: Object (Followed by the entire HTML of the template) has no method 'indexOf' at Object.exports.parse (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:144:21) at exports.compile (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:229:15) at Object.exports.render (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:289:10) at send (/home/ubuntu/workspace/routes/email.js:171:28) at fs.readFile (fs.js:272:14) at Object.oncomplete (fs.js:108:15)

虽然这样做同步工作正常。

var str = fs.readFileSync('emailTemplate.ejs', 'utf8');

var template = ejs.render(str, {

name: data.name

});

任何人都可以告诉我为什么会发生这种情况吗?

`fs.readFile()` 是 Node.js 中用于**异步读取文件内容**的核心方法,属于 `fs` 模块。它可以读取文本文件(如 `.txt`, `.json`, `.js`)或二进制文件(如图片、PDF),并支持回调函数方式处理结果。 --- ### ✅ 基本语法 ```javascript fs.readFile(path[, options], callback) ``` - `path`: 文件路径(相对或绝对) - `options`: 可选配置,如编码格式 - `callback`: 回调函数 `(err, data) => {}`,其中: - `err`: 错误对象,如果出错则不为 `null` - `data`: 读取到的数据(字符串或 Buffer) --- ### ✅ 示例 1:读取文本文件(UTF-8 编码) ```javascript const fs = require('fs'); fs.readFile('./message.txt', 'utf8', (err, data) => { if (err) { console.error('❌ 读取文件失败:', err.message); return; } console.log('✅ 文件内容:'); console.log(data); }); ``` > 🔹 如果文件是文本文件(如日志、配置文件),建议指定 `'utf8'` 编码,这样 `data` 就是字符串而不是 `Buffer`。 --- ### ✅ 示例 2:读取 JSON 文件 ```javascript const fs = require('fs'); fs.readFile('./config.json', 'utf8', (err, data) => { if (err) { console.error('❌ 无法读取 config.json:', err.message); return; } try { const config = JSON.parse(data); // 解析 JSON console.log('✅ 配置加载成功:', config); } catch (parseErr) { console.error('❌ JSON 格式错误:', parseErr.message); } }); ``` 假设 `config.json` 内容如下: ```json { "port": 3000, "debug": true } ``` 输出: ``` ✅ 配置加载成功: { port: 3000, debug: true } ``` --- ### ✅ 示例 3:读取二进制文件(如图片) ```javascript const fs = require('fs'); fs.readFile('./logo.png', (err, data) => { if (err) { console.error('❌ 读取图片失败:', err.message); return; } console.log(`✅ 图片读取成功,大小: ${data.length} 字节`); console.log('类型:', data.constructor.name); // 输出: Buffer }); ``` > 🔹 不传编码时,默认返回 `Buffer`,适用于图像、音频等二进制文件。 --- ### ✅ 方法四:使用 Promise 包装(配合 async/await) Node.js 提供了 `fs/promises` 模块,让你可以用现代 `async/await` 方式读取文件。 ```javascript const fs = require('fs').promises; async function readFileAsync() { try { const data = await fs.readFile('./message.txt', 'utf8'); console.log('✅ 文件内容:', data); } catch (err) { console.error('❌ 读取失败:', err.message); } } readFileAsync(); ``` --- ### ✅ 同步版本:`fs.readFileSync()`(阻塞主线程) 虽然不是 `readFile`,但常被对比使用: ```javascript const fs = require('fs'); try { const data = fs.readFileSync('./message.txt', 'utf8'); console.log('同步读取:', data); } catch (err) { console.error('❌ 同步读取出错:', err.message); } ``` > ⚠️ 注意:同步方法会**阻塞事件循环**,只适合启动阶段或小文件。 --- ### 🔍 参数详解 | 参数 | 类型 | 说明 | |------|------|------| | `path` | string \| Buffer \| URL | 支持多种路径格式 | | `options` | string \| object | 如 `'utf8'` 或 `{ encoding: 'utf8', flag: 'r' }` | | `encoding` | string | 常见值:`'utf8'`, `'base64'`, `'hex'`, `null`(返回 Buffer) | | `flag` | string | 文件打开行为,如 `'r'` 表示只读(默认) | --- ### 🛠 实际应用场景 #### 1. 加载模板文件 ```js fs.readFile('./template.html', 'utf8', (err, html) => { if (!err) serve(html.replace('{{title}}', '首页')); }); ``` #### 2. 动态导入本地 Markdown 文章 ```js fs.readFile('./posts/welcome.md', 'utf8', (err, md) => { if (!err) renderMarkdown(md); }); ``` #### 3. 服务启动前加载配置 ```js // 启动时同步读取(可接受) const config = JSON.parse(fs.readFileSync('config.json', 'utf8')); ``` --- ### ⚠️ 常见错误与解决方案 | 错误 | 原因 | 解决办法 | |------|------|---------| | `ENOENT: no such file or directory` | 文件不存在 | 先用 `fs.existsSync()` 判断 | | `EACCES: permission denied` | 权限不足 | 检查文件权限或运行用户 | | `Unexpected token` in JSON.parse | 文件存在但内容不是合法 JSON | 添加 try-catch 并提示格式错误 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值