js下载文件

974 阅读3分钟

下载文件

在后台的管理系统中,数据统计是必不可少的系统功能模块。因此,导出统计数据,下载文件是常见的需求。今天我们来看看实现常用的文件下载的几种方式。

window.open打开新页面下载文件

window.open(`url`, '')

这种方式,后台提供文件下载路径,我们调用window.open方法就可以实现文件下载了,简单方便,但是当参数错误时,或其它原因导致接口请求失败,这时无法监听到接口返回的错误信息,需要保证请求必须是正确的且能正确返回数据流,不然打开页面会直接输出接口返回的错误信息,体验不好。

a标签打开新页面下载

function exportFile(url,filename) {
  var link = document.createElement('a');
  var body = document.querySelector('body');
  link.href = url;
  // 自定义文件名字
  link.download = filename;
  // 兼容火狐
  link.style.display = 'none'
  body.appendChild(link);

  link.click();
  // 移除a标签
  body.removeChild(link);
}

a标签下载的方式和window.open一样,非常简单,还可以自定义下载的文件名,但是同样无法监听错误信息。而且,这两种方式在下载.mp3格式或者浏览器支持的音视频文件时,会直接播放,而不是下载这个文件。

文件流下载

为了解决下载音视频文件播放的文件,我们需要借助Blob对象和ArrayBuffer对象。

获取文件 通过axios获取文件

import axios from 'axios'
const getFile = url => {
    return new Promise((resolve, reject) => {
        axios({
            method:'get',
            url,
            responseType: 'arraybuffer'
        }).then(data => {
            resolve(data.data)
        }).catch(error => {
            reject(error.toString())
        })
    })
}

保存文件

接下来就是保持文件:

const saveAs = (blob, filename) => {
    if (window.navigator.msSaveOrOpenBlob) {
        navigator.msSaveOrOpenBlob(blob, filename);
      } else {
        const link = document.createElement("a");
        const body = document.querySelector("body");
        link.href = window.URL.createObjectURL(blob); // 创建对象url
        link.download = filename;
        // fix Firefox
        link.style.display = "none";
        body.appendChild(link);
        link.click();
        body.removeChild(link);
        window.URL.revokeObjectURL(link.href); // 通过调用 URL.createObjectURL() 创建的 URL 对象
      }
}

调用方法

export const download = (url,filename='')=>{
  getFile(url).then((blod)=>{
    // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8 excel的mimeType
    saveAs( new Blob([res],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"}),`${formatDate(new Date(), "yyyy-MM-dd")}统计数据`)
  })
}

上传文件

除了表单的形式,我们还可以借助FileReader对象来完成文件上传。

new FileReader

FileReader主要用于将文件内容读入内存,通过一系列异步接口,可以在主线程中访问本地文件。

使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要处理的文件或数据。

var reader = new FileReader();

方法

  • abort():void 终止文件读取操作
  • readAsArrayBuffer(file):void 异步按字节读取文件内容,结果用ArrayBuffer对象表示
  • readAsBinaryString(file):void 异步按字节读取文件内容,结果为文件的二进制串
  • readAsDataURL(file):void 异步读取文件内容,结果用data:url的字符串形式表示
  • readAsText(file,encoding):void 异步按字符读取文件内容,结果用字符串形式表示

事件

  • onabort 当读取操作被中止时调用
  • onerror 当读取操作发生错误时调用
  • onload 当读取操作成功完成时调用
  • onloadend 当读取操作完成时调用,不管是成功还是失败
  • onloadstart 当读取操作将要开始之前调用
  • onprogress 在读取数据过程中周期性调用

文件上传

const input = document.getElementById('file'); // input file 标签

input.onchange = function() {
  var file = this.files[0];
  if(!!file) {
    var reader = new FileReader();
    reader.readAsArrayBuffer(file);
    reader.onload = function() {
      // 读取的数据
      var binary = this.result;
      upload(binary)
    }
  }
}

function upload(binary) {
  const blob = new Blob([this.result]);
  const formdata = new formdata();
  formdata.append('file', blob);
  axios.post(url,formData).then(function (response) {
  console.log("res: ",response);
 })
}