前端如何实现文件下载功能
对于如何实现文件下载功能,根据实现的技术方式分为两大类:
- 结合后端实现
- 纯前端实现
结合后端实现
两种实现方式
第一种、直接下载服务器的静态资源
对于这种方式,最简单的是使用a标签
<a href="URL"></a>
其他的方法如form、iframe、location.href、window.open(),这里就不细讲了。
第二种、前端传参,后端生成文件
实现思路:
1、前端通过发送数据或参数给到后端
2、在由后端根据接收的数据生成文件或根据参数查找出对应的数据在生成文件
3、然后在响应请求头中设置
Content-disposition:attachment;filename="fliename.fileType"
用于指定文件类型、文件名和文件编码等
Content-disposition(内容-部署)是MIME协议类型的扩展,MIME协议指示MIME用户代理如何显示附加的文件。
4、浏览器接收到响应头后就会触发下载行为。
优缺点
优点
可以根据参数生成不同的文件,灵活性高
能实现大数据量或大文件的下载
缺点
如果需要下载的是用户生成的内容(在线作图等)或者内容已经全部返回到客户端,会造成资源和带宽的浪费
纯前端实现
纯前端实现并不是一定不需要后端,只是有时候后端的数据已经给到前端,用户下载的文件内容只需要现有的数据,这时候就可以是使用纯前端实现下载文件的功能来减小服务器资源和带宽的浪费。
数据来源
1、后端返回
2、用户输入:在线作图、在线表格输入
实现思路
分为两步:
第一步、将数据生成对应得data:URLs或blob:URLs
第二步、处理下载(或叫导出)方式
第一步、将数据生成对应得data:URLs或blob:URL
生成data:URLs
data: URLs是前缀为data:的 URL 字符串,格式为
data:[<mediatype>][;base64],<data>
mediatype 是个 MIME 类型的字符串,例如 "image/jpeg" 表示 JPEG 图像文件。
如果被省略,则默认值为 text/plain;charset=US-ASCII
如何将数据转换为data:URLs
第一种、对于文本类型,可以直接将数据拼接
示例
const dataURL = `data:text/plain;base64,` + textData
第二种、通过window.btoa()方法
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==
第三种、通过FileReader.readAsDataURL(blob)方法
对于File或Blob对象,可以使用FileReader.readAsDataURL()的方法转换为data:URLs
示例
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)
生成BlobURLs
blob: URLs是URL.createObjectURL() 静态方法创建的一个 DOMString,其中包含一个表示参数中给出的对象的URL。
URL.createObjectURL()方法只能处理File或Blob对象,所以如果要生成blobURLs则必须将数据转换为blob对象或file对象。
示例
如果数据不是File或Blob对象
const blob = new Blob([data][, MIMEType])
生成BlobURLs
const BlobURL = URL.createObjectURL(blob)
创建出来的BlobURLs需要手动调用URL.revokeObjectURL()销毁,否则会一直保留到页面关闭,为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。
第二步、处理下载(或叫导出)方式
第一种、<a>标签的download和href
其中<a>标签的download是HTML5标准新增的属性,作用是指示浏览器下载URL而不是导航到URL,因此将提示用户将其保存为本地文件。另外,download属性的值可以指定下载文件的名称。
href则支持dataURLs和blobURLs两种类型的值。
示例
<a download="filename" href="dataURLs或BlobURLs"></a>
第二种、location.href或window.open()
这个方法是直接把 DataURLs 或者 BlobURLs 传到浏览器地址中触发下载。有两种方式:
window.location.href = urls; // 本窗口打开下载 window.open(urls, '_blank'); // 新开窗口下载
第三种、msSaveOrOpenBlob(IE10+)
这是 IE 特有的方法。
navigator.msSaveOrOpenBlob(blob, fileName);
第四种、iframe(IE <= 9)
其他更现代的浏览器也支持此方法,不过此方法效率和安全性较低,所以一般只在 IE <= 9 时使用。
var frame = document.createElement("iframe"); if ( frame ) { document.body.appendChild(frame); frame.setAttribute("style", "display:none"); frame.contentDocument.open("txt/html", "replace"); frame.contentDocument.write(data); // data 是 string 类型 frame.contentDocument.close(); frame.focus(); frame.contentDocument.execCommand("SaveAs", true, filename); document.body.removeChild(frame); }
优缺点
优点
减少服务器资源和带宽
只需要前端,增加了前端的可控性
缺点
对于大数据量支持度不好
有兼容性问题