Axios下载Buffer流文件,通过Nodejs存储到本地,显示进度,可取消下载

4 篇文章 0 订阅
1 篇文章 0 订阅
Nodejs功能模块:

简介如下:
fs => 用来创建读写流
详情请查询Nodejs官网:http://nodejs.cn/api/http.html

方法功能:
服务器:文件以buffer流传输到前端(application/octet-stream)
例如:在这里插入图片描述
本地:存储到本地 => 源文件(压缩包可选择直接解压到本地)

代码如下:
/**
 * 下载Blob到本地(zip,tar,exe,dll,jpg)
 * @param {String} fileName 例:
 * @param {String} outPutPath 例: path.join(process.cwd(), 'userData');
 * @param {String} outPutName 例: jdk-8u181-linux-x64.tar.gz
 * @param callback '() => {}';
 */
let downloadRequest, CancelToken = axios.CancelToken;
export let _downLoadBlob2Local = (fileName, outPutPath, outPutName, callback) => {
  let streamLocal;
  if (outPutName) {
    streamLocal = new WritableStream(fs.createWriteStream(path.join(outPutPath, outPutName)));
  }
  axios.post('URL路径', { '参数': fileName }, {
    responseType: 'blob', // 重点
    onDownloadProgress: (event) => { // 下载进度
      // event.total为0时
      let total = event.target.getResponseHeader('Content-Length');
      // event.total不为0
      // let percentage = parseInt((event.loaded / event.total) * 100)
      let percentage = parseInt((event.loaded / total) * 100) > 100 ? 100 : parseInt((event.loaded / total) * 100);
      console.log('percentage:', percentage);
    },
    cancelToken: new CancelToken(function executor (c) { // 取消下载
      downloadRequest = c;
    })
  }).then((res) => {
    if (res.status === 200) {
      let blob = new Blob([res.data]);
      if (streamLocal) {
        // 生成源文件
        blob.stream().pipeTo(streamLocal);
        callback && callback();
      } else {
        // 通过JSZip直接解压到本地
        buffer2files(blob, outPutPath, fileName, callback);
      }
    } else {
      alert('错误码:' + res.status);
    }
  }).catch(err => { throw err })
}

/**
  * 取消下載
  * @param callback '() => {}';
  */
export let _abortDownload = (callback) => {
  downloadRequest();
  callback && callback();
}

/**
  * buffer格式的内容写到对应的目录
  * @param {Object}  file zip 本地或远程读取的文件
  * @param {String}  outPutPath 例: path.join(process.cwd(), 'userData');
  * @param callback '() => {}';
  */
export let buffer2files = (file, outPutPath, fileName, callback) => {
  let newZip = new JSZip();
  let jszipresults = [];
  let jszipresult = () => {
    return new Promise(resolve => {
      newZip.loadAsync(file)
        .then((file) => {
          dofile(newZip, outPutPath, file);
          resolve();
        });
    });
  };
  jszipresults.push(jszipresult());
  Promise.all(jszipresults).then(() => {
    // 解压后删除zip文件
    (fileName && fs.existsSync(path.join(outPutPath, fileName + '.zip'))) && fs.unlinkSync(path.join(outPutPath, fileName + '.zip'))
    callback && callback();
  });
}

/**
  * 解压相关
  * @param {Object}  newZip
  * @param {String}  outPutPath
  * @param {Object}  file
  */
let dofile = (newZip, outPutPath, file) => {
  let files = file.files;
  for (let f in files) {
    let zipObj = files[f];
    let fileName = f.substring(f.lastIndexOf('/') + 1);
    let filePath = f.substring(0, f.lastIndexOf('/') + 1);
    !zipObj.dir && newZip.file(f).async('nodebuffer') // 读取压缩包中文件
      .then(function (content) {
        // 生成文件/文件夹
        fs.mkdirSync(path.join(outPutPath, filePath), { recursive: true });
        // 写入本地
        _writeTxtToFileSync(path.join(outPutPath, filePath, fileName), content)
      });
  }
}

/**
  * 同步写入
  * @param {String} fullPath 路径 例:xx/x/x.json
  * @param {String} newTxt,写入到文件的字符串数据
  */
export let _writeTxtToFileSync = (fullPath, newTxt) => {
  try {
    fs.writeFileSync(fullPath, newTxt);
  } catch (e) {
    alert(e);
    console.error(e);
  }
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 使用axios下载文件有以下几个原因。首先,使用axios可以提供更好的安全性。通过使用axios发送请求,可以在请求头中添加token进行权限校验,确保只有具有合法权限的用户才能下载文件。这可以有效防止恶意用户通过修改请求参数获取到服务器的下载数据。\[3\]其次,使用axios可以提供更好的文件下载方式。通过设置axios的responseType为'blob',可以将后台返回的数据强制转换为blob类型,从而实现文件下载。然后,可以通过创建一个下载链接,并设置相应的文件名,使用户可以方便地下载文件。\[2\]最后,使用axios可以提供更好的兼容性。通过使用axios发送请求,可以兼容不同浏览器的下载操作,包括兼容火狐浏览器。\[2\]综上所述,使用axios下载文件可以提供更好的安全性、更好的文件下载方式和更好的兼容性。 #### 引用[.reference_title] - *1* *3* [使用axios实现文件下载的安全问题](https://blog.csdn.net/weixin_43236062/article/details/120531829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [axios获取后端文件get/post下载Excel,详细步骤以及踩过的坑](https://blog.csdn.net/weixin_53350466/article/details/126469254)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值