Skip to main content

前端如何实现文件下载

前端如何实现文件上传

下载文件的方式首先分为两大类:

  • 后端控制下载
  • 前端下载

后端控制下载

前端跳转

直接下载服务器静态资源。

<a href="下载地址"></a>

还可以通过form``iframe``location.href``window.open()等方式。

前端发起请求

前端发起请求传参,由后端根据请求和参数生成文件,同时后端在响应请求头中设置Content-disposition指定文件类型、文件名和文件编码等。

Content-disposition:attachment;filename="fliename.fileType"

Content-disposition(内容-部署)是 MIME 协议类型的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。 浏览器在接收到响应头后就会触发下载行为。

前端下载

前端下载是指后端将数据返回给前端,由前端处理数据并控制浏览器下载文件(或者叫导出文件)

分为两步:

  1. 处理数据,将数据生成对应的data:URLsblob:URLs,这步是重点
  2. 处理下载(或叫导出)方式

处理数据

生成 data:URLs

data:URLs是前缀为data:URL字符串,格式为data:[<mediatype>][;base64],<data> > mediatype是个MIME类型的字符串,例如"image/jpeg"表示JPEG图像文件 如果被省略,则默认值为text/plain;charset=US-ASCII

  1. 对于文本类型,可以直接将数据拼接
const dataURL = `data:text/plain;base64,` + textData
  1. 对于二进制数据,通过 window.btoa()方法,生成 base-64 编码的 ASCII 字符串,然后拼接
let str = new Blob(['some thing'])
console.log(btoa(str)) // W29iamVjdCBCbG9iXQ==
let dataURL = 'data:text/plain;base64,' + btoa(str) // data:text/plain;base64,W29iamVjdCBCbG9iXQ==
  1. 对于FileBlob对象,通过FileReader.readAsDataURL()方法直接转换
const blob = new Blob(['some thing'])
const reader = new FileReader()
reader.onloadend = function () {
const dataURL = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;')
}
reader.readAsDataURL(blob)

生成 blob:URLs

blob:URLsURL.createObjectURL()静态方法创建的一个DOMString,其中包含一个表示参数中给出的对象的URLURL.createObjectURL()方法只能处理FileBlob对象,所以如果要生成blob:URLs则必须将数据转换为Blob对象或File对象。

const blob = new Blob([data][, MIMEType]) // 转成Blob对象
const BlobURL = URL.createObjectURL(blob) //生成blob:URLs

创建出来的blob:URLs需要手动调用URL.revokeObjectURL()销毁,否则会一直保留到页面关闭。

下载方式

// a标签
const a = document.createElement('a')
a.download = fileName
a.href = urls
a.click()
// location.href
window.location.href = urls
// window.open()
window.open(urls, '_blank')
// msSaveOrOpenBlob() IE10+特有方法
navigator.msSaveOrOpenBlob(blob, fileName)