基于Blod的ajax进度条下载实现示例代码
普通浏览器下载
在网页开发中,如果你想下载,你经常使用新打开的网页或iframe。实现其实很简单:
A target=' _ blank ' href=' download . zip ' rel=' external no follow '单击download /a//或iframe style=' display : none ' src=' http : download . zip '/iframe用户单击A选项卡弹出新选项卡后,或打开iframe后,浏览器实际上所谓的附件下载是指浏览器读取响应消息的头后,会生成下载提示框,用户确认后会继续下载文件。文件实际上是一个流。所谓流,就是一个传输过程。浏览器将自动管理这一传输过程,并自动生成进度条、停止下载按钮、继续按钮、取消下载按钮和用于更新和下载字节的显示按钮。这些都是浏览器为我们自动完成的,整个过程是我们无法控制的。
Ajax下载
浏览器对下载的支持基本可以满足我们的需求,在一般场景下探索其他下载方式意义不大。但还是有一些场景是浏览器下载无法满足的,比如要求我们的web应用监控下载进度,或者在下载完成后触发特定事件,或者web应用可以自动取消下载过程,或者使用worker创建后台运行的下载等。对于上述情况,我们可以使用基于Blod对象的ajax下载。
ajax下载附件和ajax上传附件一样,都需要浏览器支持ajax2.0,其实所谓的下载和普通的Ajax请求没有什么不同,它是一个对url地址的请求,但是下载的一般是二进制文件,不是文本对象或者json对象,JavaScript需要提供一个可以封装这个二进制文件的类型,就是blod。因此,要设置响应类型,响应类型的值为“blod”:
var xhr=new XMLHttpRequest();xhr.open(option.type?option . type . touppercase()' : ' GET ',url,true);xhr.responseType=' blobXMLHttpRequest对象的响应类型字段值必须是blob。布洛德的目标是什么?
Blod对象
MDN将其描述为:
Blob对象是包含只读原始数据的类文件对象。Blob对象中的数据不必是JavaScript中的本机形式。文件接口基于Blob,继承了Blob的功能,并扩展到支持用户计算机上的本地文件。使用Blob对象,我们可以将二进制流封装为一个对象。
如果你知道html5的文件相关api,你应该对blod对象并不陌生。Blod可以将一个字节流封装到一个文件中,而XMLHttpRequest对象的responseType值是blob,所以我们可以将响应体作为blob对象来对待。
Xhr.onload=function () {//如果(这。status=200 this . status 300){ var blob=new blob([this。响应],{type: this。response . type });}}使用ajax下载文件,然后将文件保存为blob对象并缓存在浏览器中。那么如何让用户把文件保存到硬盘上呢?
将blob对象保存在硬盘上
我们可以模拟浏览器下载,生成一个A标签或者iframe,然后生成一个url,这样我们就可以下载回浏览器,浏览器会自动生成一个保存附件的窗口。Url可以通过url.createObjectURL(Blob)获得。createObjectURL支持blob对象和File对象,并且可以生成一个虚拟URL,以便当前用户可以访问这些对象,包括下载。与直接从服务器下载不同,这里的下载是客户端内部的,不需要网络io,所以下载几乎是瞬间完成的。但是这个url生成后,就应该释放,否则blob资源不会被垃圾收集,可以通过使用url.revokeObjectURL释放这个URL,这样就可以释放blob资源。对于ie浏览器,它有自己的一套Blob对象处理策略,这是两个导航器方法:msSaveOrOpenBlob和msSaveBlob。
//ie if(window . navigator . mssaveropenlob){ navigator . mssavelob(blob,filename)的下载;} else {//non-ie download var link=document . create element(' a ');link.href=window。URL . CreateObjectURl(blob);link.download=fileNamelink . click();窗户。URL . revokeobjecturl(link . href);}进度条并取消下载
然后是进度条和下载取消功能。事实上,XMLHttpRequest对象有一个进度事件,但是我们在发出ajax请求时通常会忽略它。毕竟,一般的请求都是即时的,所以没有必要为它们设置进度条。然而,ajax下载是不同的。下载附件需要时间,所以有必要为它们开发一个进度条。通过监控进度事件,我们可以得到下载进度。
使用XMLHttpRequest对象的中止功能取消下载。此外,load事件可以监视下载完成,error事件可以监视下载失败。总之,ajax下载和普通ajax请求的事件和方法完全相同。
性能优化及相应策略
Ajax下载和长连接一样,比普通请求占用更多带宽,尤其是下载占用更多带宽的时候。因此,在下载过程中可能会阻塞其他ajax请求,因此建议ajax下载的资源和其他请求的资源使用不同的域名,但这会带来一个新的问题————同源策略。
同源策略是浏览器安全的基石。没有相应的政策,任何网站都可能发出csrf攻击。如果不能保证下载资源的url与当前页面的url相同,则会触发相同的源策略,下载会失败,因此需要ajax跨域处理。相比iframe和new tab的下载方式(其实iframe也有同源策略,要求iframe中的页面和父页面不能访问对方的内容,但是下载功能不涉及访问对方内容的这个操作,所以iframe下载不受同源策略的影响),ajax下载本质上就是ajax,所以会受到浏览器同源策略的影响。因此,如果下载非同源附件,则需要附件所在的服务器支持cors,如果服务器需要访问cookie,则需要将XMLHttpRequest对象的withCredentials设置为true。
同时,由于同源策略,我们不能以ajax的形式下载第三方资源,因为通常的下载服务不做cors处理。与iframe下载或new tab下载相比,它不受同源策略的影响,所以不需要做cors处理。这极大地限制了ajax下载的适用性。
总结:
最后,我们将总结ajax下载的使用场景:
1.需要监控下载进度,比如发现用户下载进度太慢,主动提供其他解决方案。
2.下载后需要触发特定事件,例如弹出桌面提示通知。
3.需要提供后台下载。例如,我们可以在用户打开网页并缓存后秘密下载附件,然后在用户真正想下载附件时保存在本地。我们甚至可以在worker的帮助下创建一个后台线程,这样可以保证下载过程不会影响页面的正常呈现。
4.下载后,不会保存在硬盘中,但附件会由webapp直接处理。例如,Pdf.js是由ajax下载的。
最后,我展示了一个ajax下载的演示:Ajax downloademo _ jb51.rar。
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:基于Blod的ajax进度条下载实现示例代码是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。