node.js - Node JS - 在promise-ftp上没有管道无法获取流数据
问题描述
大家好,当我尝试从 FTP 获取文件然后通过我的 API 作为 base64 发送时,我遇到了我的 Node.js api 与 Express 的问题。
我正在使用 -> promise-ftp ( https://www.npmjs.com/package/promise-ftp )。
这是端点的样子:
getData = (req, res, next) => {
const ftp = new PromiseFtp();
let data = [];
ftp.connect({host: 'xxxl',user: 'xxx',password: 'xxx'})
.then(() => {
return ftp.get('xxx.pdf');
}).then((stream) => {
return new Promise((resolve, reject) => {
stream.once('close', resolve);
stream.once('error', reject);
stream.pipe(fs.createReadStream('test.pdf'));
stream
.on('error', (err) => {
return res.send({errorMessage: err});
})
.on('data', (chunk) => data.push(chunk))
.on('end', () => {
const buffer = Buffer.concat(data);
label = buffer.toString('base64');
return res.send(label);
});
});
}).then(() => {
return ftp.end();
});
}
问题是我不想将此文件本地保存在 api 文件旁边,当我删除行时stream.pipe(fs.createReadStream('test.pdf'));
它不起作用。
我不确定管道在这里做什么。
你能帮帮我吗?
解决方案
readable.pipe(writable)
是 Node 的 Stream API 的一部分,它透明地将读取的数据写入可写流,为您处理背压。无需将数据通过管道传输到文件系统,ExpressResponse
对象实现了可写流接口,因此您可以将 FTP 承诺返回的流直接通过管道传输到res
对象。
getData = async (req, res) => {
const ftp = new PromiseFtp();
try {
await ftp.connect({host: 'xxxl',user: 'xxx',password: 'xxx'});
const stream = await ftp.get('xxx.pdf');
res.type('pdf');
await new Promise((resolve, reject) => {
res.on('finish', resolve);
stream.once('error', reject);
stream.pipe(res);
});
} catch(e) {
console.error(e);
} finally {
await ftp.end();
}
}
如果你没有支持async
/的 Node 版本await
,这里是 Promise-only 版本:
getData = (req, res) => {
const ftp = new PromiseFtp();
ftp
.connect({host: 'xxxl',user: 'xxx',password: 'xxx'})
.then(() => ftp.get('xxx.pdf'))
.then(stream => {
res.type('pdf');
return new Promise((resolve, reject) => {
res.on('finish', resolve);
stream.once('error', reject);
stream.pipe(res);
});
})
.catch(e => {
console.error(e);
})
.finally(() => ftp.end());
}
在这里,您有一个很好的使用 Promise 的finally()
- 方法或try/catch/finally
块的用例,这将确保ftp.end()
即使发生错误也会被调用。
请注意,我故意省略了将错误发送回客户端,因为这样做可能会泄漏敏感信息。更好的解决方案是使用请求上下文设置适当的服务器端日志记录。
推荐阅读
- groovy - 无法从非 gui 模式运行 Jmeter 测试
- node.js - cloudinary 文件太大
- javascript - 如何将函数从一个文件导出到另一个 node.js?
- python - 错误 django-softdelete:命令出错,退出状态为 1:python setup.py egg_info 检查日志以获取完整的命令输出
- python - 使用python执行Mysql存储过程
- python-3.x - 如何将单线程代码转换为多线程代码
- arrays - SwiftUI中数组的值和标题列表
- javascript - Javascript:如何更改 URL 中的路径名
- jbpm - 在 JBPM 脚本任务中,我可以访问流程变量的最后更新信息吗
- javascript - 额外的编码查询来自哪里,它是什么意思?