javascript - node.js axios 下载文件流和writeFile
问题描述
我想下载一个pdf文件axios
并保存在磁盘(服务器端)上fs.writeFile
,我试过:
axios.get('https://xxx/my.pdf', {responseType: 'blob'}).then(response => {
fs.writeFile('/temp/my.pdf', response.data, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
});
文件已保存,但内容已损坏...
如何正确保存文件?
解决方案
实际上,我相信之前接受的答案有一些缺陷,因为它不能正确处理 writestream,所以如果你在 Axios 给你响应之后调用“then()”,你最终会得到一个部分下载的文件。
当下载稍大的文件时,这是一个更合适的解决方案:
export async function downloadFile(fileUrl: string, outputLocationPath: string) {
const writer = createWriteStream(outputLocationPath);
return Axios({
method: 'get',
url: fileUrl,
responseType: 'stream',
}).then(response => {
//ensure that the user can call `then()` only when the file has
//been downloaded entirely.
return new Promise((resolve, reject) => {
response.data.pipe(writer);
let error = null;
writer.on('error', err => {
error = err;
writer.close();
reject(err);
});
writer.on('close', () => {
if (!error) {
resolve(true);
}
//no need to call the reject here, as it will have been called in the
//'error' stream;
});
});
});
}
这样,您可以调用downloadFile()
,调用then()
返回的承诺,并确保下载的文件已完成处理。
或者,如果你使用更现代的 NodeJS 版本,你可以试试这个:
import * as stream from 'stream';
import { promisify } from 'util';
const finished = promisify(stream.finished);
export async function downloadFile(fileUrl: string, outputLocationPath: string): Promise<any> {
const writer = createWriteStream(outputLocationPath);
return Axios({
method: 'get',
url: fileUrl,
responseType: 'stream',
}).then(async response => {
response.data.pipe(writer);
return finished(writer); //this is a Promise
});
}
推荐阅读
- excel - 基于另一列在 Excel 中从 1 列计数或选择
- elasticsearch - 将 _id 添加到源中作为索引中所有现有文档的单独字段
- android - Retrofit Android - 将标头添加到现有的 Retrofit 对象
- amazon-web-services - 跟踪在 DynamoDB 表中删除/更新/插入项目的角色/身份
- go - 将 []interface{} 转换为 []string 类型
- html - 滚动时导航栏和徽标保持在一起?
- html - Javascript游戏保存变量
- c# - 如何编辑大文件?
- azure - AZ CLI 无法识别 Azure DevOps 参数
- pytorch - 如何访问序列网络中激活函数的学习参数的值