前端下载带来的一些思考

前言

最近集中遇到了HTTP相关方面的问题,意识到自己的HTTP协议一些细节点掌握的还不够,而前端实现下载是日常中非常常见的点,从下载为起点引发了一系列的思考。

思考的问题如下:

  • 为什么不能直接使用Ajax实现下载?
  • 前后端接口传参,参数类型是什么?

    而本文也会围绕这两个问题进行探讨。

具体分析

为什么不能使用Ajax直接实现下载?

场景

业务要求实现导出文件功能,后台给了一个二进制流形式下载的Get类型接口

你想:使用项目中ajax库来发送给Get请求,应该就可以了吧
你“键步”如飞,敲下一行get请求代码,发现没有效果

你Google了一下,发现使用a标签可以实现,就使用a标签+download来实现了下载。

但是为什么呢?这个想法一直缠绕着你。
疑问

a标签就是发送一个Get请求,使用Ajax也是发送个Get请求,一个可以实现下载,一个不可以,差异就是二者的区别了。

在网上你找到了答案:

a标签+download会触发浏览器的下载机制

那是不是可以这么认为Ajax不会触发浏览器的下载机制呢?实际上就是如此。

Ajax就是使用XMLHttpRequest对象实现的:

var xhr = new XMLHttpRequest();
xhr.open(method,url);
xhr.onreadystatechange = function() {
  if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
    console.log(xhr.responseText)
  }
};
xhr.send(data);

请求成功之后,你要获取请求到的数据:

response、responseText、responseXML

responseText实际上就是文本,即DOMString类型
responseXML实际是处理html/xml的Document类型

response实际上是包含所有类型的结果即responseType的类型,具体的类型有:

数据类型
‘’DOMString(文本类型)
arraybufferArrayBuffer(二进制数组)
blobBlob(二进制流)
documentDocument(文档html/xml等)
jsonJSON可以通过JS的parse转换成js对象
textDOMString(文本类型)

通过response你可以获取服务器端传递的各种形式的数据

实际上responseType与Http中Content-type对应,不过是一对多的关系,例如:

Document可与text/html、text/xml等MIME对应

就上面的场景:

Ajax获取到二进制流内容之后,其不会自动触发浏览器的下载机制,这就是不能直接使用ajax下载的原因

总结
可以实现下载的方式:

  • 使用saveAs浏览器命令来实现下载
  • 使用a标签 + download 或 a标签 + download + URL.createObjectUrl()
  • 使用window.open + URL.createObjectUrl() 或 FileReader
  • 使用location.href + URL.createObjectUrl() 或 FileReader
  • 使用Form表单来实现下载
  • 使用iframe来实现下载
  • 使用ajax + FormData来模拟表单提交

实际上前4种正是FileSaver源码的实现方式,具体可看之前FileSaver源码分析这篇文章。

前后端接口传参,参数类型是什么?

场景

后台接口要求number类型的时间戳,而传递到后台的类型到底是什么

实际上上面的场景正是HTTP本质的体现

HTTP是基于ASCII的即请求行和首部字段都是ASCII流传输的,而实体部分是字节流传输

物理底层都是比特流,在HTTP中传输,数据都是字符串即JS中数组、Number、Boolean类型在到达服务器上应用程序都是文本,传递到服务器上的参数类型都是文本,不存在什么类型,具体的类型实际上服务器应用程序处理决定的。

Content-type指定实体部分内容类型或字符编码,服务器端根据这里来处理转换实体内容。

总结

实际上上面这两个问题,涉及到的知识点相当多例如HTTP、字符集、解码、编码等等,只是简单的从表象谈了谈,希望之后能够更加深入研究研究。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值