引子

在HTML5没来之前,浏览器想要下载文件,可能有这么几种方式:

  1. 借助a标签,<a href="学习资料.xlsx"></a>

  2. window.location = '学习资料.xlsx'

  3. 借助浏览器插件,如flash等(没考证过)

除了第三外,前两种方法有个缺点,就是无法知道下载是否完成,因为浏览器没有给出相关的事件。但是,自从有了Blob,fetch, xhr2这些好用的API之后,ajax下载文件(小文件)就变得可行了,核心原因就在于Blob和ArrayBuffter这些API提供给了浏览器操作二进制文件的能力。接下来就开始我的表演

1. fetch方法

fetch优点有很多,比如基于promise,写起来直观易懂,缺点是IE,包括IE11全部不支持。

使用时要注意一点是,fetch请求时默认不会带上cookie,如果你的api是在登录后才能访问,记得手动设置 credentials选项。下面是下载一个文件的代码:


fetch('学习资料.xlsx', {
method: 'GET',
credentials: "same-origin"// 带上cookie
})
.then(res => res.blob()) .then(blob => {
saveAs(blob) //fileSaver.js中的方法
})

从上面可以看出,调用fetch时会返回一个promise,当promise resolve时,会传出一个Response的实例(res),这个res除了有statusstatusTextok 这几个属性用于获取服务器相应的状态值外,还有几个炫酷的方法,正式这几个方法,使浏览器可以请求的数据类型不再局限于文本,他们是:

res.blob() //返回值是一个promise,promise resolve后会拿到一个blob对象
res.json() //返回值是一个promise,promise resolve后会拿到一个json对象,无需再调用JSON.parse
res.text() //返回值是一个promise,promise resolve后会拿到一个字符串
res.formData() //返回值是一个promise,promise resolve后会拿到一个表单数据对象(formData)

所以拿到blob后,接下来就是触发浏览器的下载了,这里调用了一个saveAs函数,它来自FileSaver.js,一个不用请求api也可以触发浏览器下载动作的库,它接受一个blob对象,和一个可选的文件名称参数,就能触发下载动作。

2.xhr2方法

xhr2的兼容性比fetchAPI要好,兼容到IE10,它没有向fetch一样把难用的xhr推翻重做,而是做了一些有用的扩展,比如xhr.responseType,在发起请求前,通过设置这个属性,可以使浏览器对返回的数据进行处理,就像res的那些有用的方法一样。xhr.responseType可以取下列值:

  "arraybuffer",
"blob",
"document",
"json",
"text"

没错,就是和上面的res的那些方法殊途同归。当请求数据返回时,你可以从xhr.response拿到相应的数据。为什么不是res.responseText呢?很明显这是xhr1时期的,从这个属性只能拿到字符串,是满足不了我们的需求的。

接下来的事情就跟上面一样了,照例贴一下代码:

      var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.open('GET', url, true);
xhr.onload = function(){
var res = xhr.response;
if(res){
saveAs(res, filename);
}
}
xhr.send();

到这里,你就可以从容掌握文件下载的状态了。最后再啰嗦一句,xhr.onload也是xhr2增加的事件,有了它,再也不想用xhr.onReadyStateChange了。其他新增的事件还有'onprocess', 'onerror', 'onabort', 'onloadstart','onloadend', 'ontimeout'。(完)

最新文章

  1. HDU 1859
  2. HTML和CSS经典布局4
  3. Anciroid的IPC机制-Binder概述
  4. Python For Data Analysis -- Pandas
  5. BigDecimal进行除法divide运算注意事项
  6. IIS7下w3wp.exe进程CPU100%问题解决办法
  7. HDU 1020 Encoding POJ 3438 Look and Say
  8. Directx11学习笔记【四】 封装一个简单的Dx11DemoBase
  9. Python3:字符串的大小写和镜像字符串(swapcase()函数,chr(),ord(),translate()函数)
  10. HDU 1088(文本处理 **)
  11. Java 容器源码分析之HashMap多线程并发问题分析
  12. 5,注释、分支结构、循环结构、伪&ldquo;选择结构&rdquo;
  13. [可能没有默认的字体]Warning: imagettfbbox() [function.imagettfbbox]: Invalid font filename...
  14. 安装pyenv virtualenv
  15. mfc 引用
  16. Elasticsearch5.X IN Windows 10 系列文章(5)
  17. android ndk opencv jni 编译集成
  18. 安装git之后,桌面图标出现很多的蓝色问号
  19. php中的foreach问题(1)
  20. 数据写入到TXT文档中

热门文章

  1. Topcoder-SRM-#712-Div2
  2. MFC模块状态(一)
  3. *单链表[递归&amp;不带头结点]
  4. 通过request获取网页资讯 通过BeautifulSoup剖析网页元素
  5. POJ1274 The Perfect Stall
  6. python_列表、元组、字典、集合对比
  7. HDU2732一个让我debug了一晚上的题目
  8. [置顶] 获取网络数据中的数组显示成ListView的简单流程
  9. vue项目webpack中Npm传递参数配置不同域名接口
  10. Sql Server Report 导出到EXCEL 指定行高