下载文件的方式首先分为两大类:
- 后端控制下载
- 前端下载
后端控制下载
前端跳转
直接下载服务器静态资源。
<a href="下载地址"></a>
还可以通过form``iframe``location.href``window.open()
等方式。
前端发起请求
前端发起请求传参,由后端根据请求和参数生成文件,同时后端在响应请求头中设置Content-disposition
指定文件类型、文件名和文件编码等。
Content-disposition:attachment;filename="fliename.fileType"
Content-disposition(内容-部署)是 MIME 协议类型的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。 浏览器在接收到响应头后就会触发下载行为。
前端下载
前端下载是指后端将数据返回给前端,由前端处理数据并控制浏览器下载文件(或者叫导出文件)
分为两步:
- 处理数据,将数据生成对应的
data:URLs
或blob:URLs
,这步是重点 - 处理下载(或叫导出)方式
处理数据
生成 data:URLs
data:URLs
是前缀为data:
的URL
字符串,格式为data:[<mediatype>][;base64],<data>
>mediatype
是个MIME
类型的字符串,例如"image/jpeg"
表示JPEG
图像文件 如果被省略,则默认值为text/plain;charset=US-ASCII
- 对于文本类型,可以直接将数据拼接
const dataURL = `data:text/plain;base64,` + textData
- 对于二进制数据,通过 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==
- 对于
File
或Blob
对象,通过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:URLs
是URL.createObjectURL()
静态方法创建的一个DOMString
,其中包含一个表示参数中给出的对象的URL
。URL.createObjectURL()
方法只能处理File
或Blob
对象,所以如果要生成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)