node.js axios下载文件流并写入File [英] node.js axios download file stream and writeFile

查看:83
本文介绍了node.js axios下载文件流并写入File的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 axios 下载pdf文件,并使用 fs.writeFile 保存在磁盘(服务器端)上,我已经尝试过:

i want download a pdf file with axios and save on disk (server side) with fs.writeFile, i have tried:

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!');
    });
});

文件已保存,但内容已损坏...

the file is saved but the content is broken...

如何正确保存文件?

推荐答案

实际上,我相信先前接受的答案存在一些缺陷,因为它不能正确处理写流,因此如果您调用"then()",在Axios给您答复后,您最终将拥有部分下载的文件.

Actually, I believe the previously accepted answer has some flaws, as it will not handle the writestream properly, so if you call "then()" after Axios has given you the response, you will end up having a partially downloaded file.

当下载稍大的文件时,这是一个更合适的解决方案:

This is a more appropriate solution when downloading slightly larger files:

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(),并确保已下载的文件已完成处理.

This way, you can call downloadFile(), call then() on the returned promise, and making sure that the downloaded file will have completed processing.

或者,如果您使用更新版本的NodeJS,则可以尝试以下方法:

Or, if you use a more modern version of NodeJS, you can try this instead:

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
  });
}

这篇关于node.js axios下载文件流并写入File的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆