资讯专栏INFORMATION COLUMN

前端培训-初级阶段-场景实战(2019-06-06)-下载文件&下载进度

sPeng / 2254人阅读

摘要:前端最基础的就是。一个朋友的问题,监测下载进度。这节主要是讲如何使用,以及前端下载的核心操作。下载文件,并显示进度条。下载文件,并显示进度条下载文件上面已经实现了,那我们先说说如何显示进度条。实现代码如下,我们操作成读流,然后统计长度。

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

这两天,碰到了不止一次前端下载的的问题。其实之前我写过一篇文章 download使用浅析,主要依靠 download 属性来实现浏览器端下载,因为是走浏览器的下载,所以没有进度条。今天我们就来说说我的解决方案。

sf 的一个问题,需要显示进度条。答案地址,问题地址

一个朋友的问题,下载的文件需要 headers 验证,无奈只能 ajax 拿数据,但是拉回来的还是字符串,需要自己处理。

一个朋友的问题,监测下载进度。

今天我们要讲什么?

如何使用 download 属性,下载文件。
这节主要是讲如何使用,以及前端下载的核心操作。

下载文件,并显示进度条。
这节是正常操作,如果你只为了解原理,看到这里就够了

其他数据类型如何互相转换
这节就不一样了。因为之前的 api 是使用 blob 实现,但是 ajax 传回来的数据有好多种类型,我们如何将他们相互转换?

如何使用 download 属性,下载文件。

download使用浅析 这一文中已经介绍了,可以去看看。我这里简单说一下。标签如果设置了 download 属性,他就会去下载这个地址。测试地址-原生 download 属性测试。

下载文件,并显示进度条

下载文件上面已经实现了,那我们先说说如何显示进度条。

显示进度条

其实浏览器也是有进度条的,但是咱们拿不到。那我们就来模拟一下载,然后显示进度条。

ajax 实现下载进度条,测试地址-显示进度条

xhr = new XMLHttpRequest();
xhr.open("get", file1.url);
xhr.onprogress = (e)=>console.log(e)//e 就是一个 ProgressEvent 对象,其中 loaded 是已下载的, total 是总大小。
xhr.send()

fetch 实现下载进度条,测试地址-fetch显示进度条并下载
fetch 的实现上来说有一些功能是没有的,比如 abort、进度等。那我们就需要去通过一些别的手段来模拟实现。
实现代码如下,我们操作成读流,然后统计长度。

下载文件

进度条已经显示好了,那我们可以下载文件了。首先我们要分几种情况

缓存下载(一个资源如果已经下载完了,再次去访问)

本地下载(资源已经在浏览器中)

blob url 下载 如这种地址 blob:https://www.lilnong.top/deb4c297-821c-4545-9b23-0fbdd76890c7

base64 url 下载 如这种地址 data:application/octet-stream;base64,aGVsbG8gbGlub25n

  blob = new Blob(["hello linong"])
  freader = new FileReader()
  freader.readAsDataURL(blob)//将 blob 读成 dataurl
  freader.onload=e=>console.log(freader.result)// 异步的,所以需要回调里面拿

无缓存下载(资源没在本地,也没有缓存)

情况就是上面几种,那我们要做的其实就是统一一下流程

ajax 拉取数据(显示进度条)

缓存了数据,然后下载缓存(因为是缓存,所以秒下)

浏览器缓存
我比较推荐用这个,因为其他的方案都有大小或者兼容上的问题。但是这个缓存需要服务器设置需要走缓存。

bloburl 本地缓存下载
这个方案在移动端异常,pc端正常,感兴趣的小伙伴可以自己实现一下,毕竟学了这么多,得用起来才能变成自己的

dataurl 本地缓存下载
这个方案的支持会比 bloburl 好一点,但是只适用于小文件。

实现前端下载文件并显示进度条

我们让 ajax 直接返回 blob。然后构建 bloburl 用于下载。

downloadFile2 = (url)=>{
    var xhr = new XMLHttpRequest();
    xhr.open("get", url);
    xhr.responseType="blob";//这是精髓
    xhr.onprogress = onprogress2;//下载进度
    // .upload.onprogress 这个是上传的时候的进度
    xhr.onreadystatechange = ()=>{
        if(xhr.readyState == 4 && xhr.status == 200){
            nativeDownload(URL.createObjectURL(xhr.response))
        }
    }
    xhr.send()
}
其他类型转换为 blob

如果是一些封装过的 ajax,没办法使用 xhr.responseType="blob" 之类的,返回回来是字符串。那我们需要怎么出转换呢?

blob to *

blob 需要配合 FileReader 来读取

blob to arrayBufferreadAsArrayBuffer
通用的、固定长度的原始二进制数据缓冲区

var fileReader = new FileReader();
fileReader.readAsArrayBuffer(xhr.response);//xhr.reponse 是 blob 类型
fileReader.onload = e=>console.log(fileReader.result);

blob to DataURLreadAsDataURL

Base64 是一组相似的二进制到文本(binary-to-text)的编码规则,使得二进制数据在解释成 radix-64 的表现形式后能够用 ASCII 字符串的格式表示出来。Base64 这个词出自一种 MIME 数据传输编码。 --MDN

blob to TextreadAsText
以字符串表示所读取的文件内容

blob to BinaryStringreadAsBinaryString
文件的原始二进制数据

* to blob

arrayBuffer to blob
new Blob([arrayBuffer], {type: "image/jpeg"})

base64 to blob

(new Uint8Array(Array.from(atob(base64url.split(",")[1])).map(v=>v.charCodeAt()))).buffer
//base64url.split(",")[1] //截取不要 data:images/jpeg;base64, 这串
//atob //转换成 BinaryString
//Array.from //转换成数组
//map(v=>v.charCodeAt()) //转换成对应的 ascii 码
//Uint8Array 转换成 Uint8Array 然后输出 buffer

BinaryString to blob
方案同上,因为上面的也是转换成了BinaryString

Text to blob
ajax 默认就是 Text 类型的返回值。这个我觉得是编码类型的转换,比如 utf-8 to ascii,目前我还没找到好的实现方法。

总结

之前就写过一篇AJAX 的进阶使用(Blob、ArrayBuffer、FormData、Document、JSON、Text),里面讲了这些支持的类型。
base64转换上传,也写过这样的。

前端目前需要操作的东西越来越多了。

在最上面那个问答里,有个库去实现 download 操作。实现原理可以自己去看看。

后记 参考资料

Data URLs --MDN

StringView

字符编码中ASCII、Unicode和UTF-8的区别

String​.prototype​.char​CodeAt()

DOMString

rfc2397

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109927.html

相关文章

  • 前端培训-初级阶段-场景实战2019-06-06)-下载文件&下载进度

    摘要:前端最基础的就是。一个朋友的问题,监测下载进度。这节主要是讲如何使用,以及前端下载的核心操作。下载文件,并显示进度条。下载文件,并显示进度条下载文件上面已经实现了,那我们先说说如何显示进度条。实现代码如下,我们操作成读流,然后统计长度。 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(H...

    freecode 评论0 收藏0
  • 前端培训-初级阶段-场景实战2019-06-06)-Content-Type对照表及日常使用

    摘要:前端最基础的就是。数据被编码为键值对。大法好,精准识别,也算是正确的表单提交。全局的默认值实例默认值创建实例时设置配置的默认值在实例已创建后修改默认值拦截器,可以拦截错误,进行上报。参考资料类型看云 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水...

    mayaohua 评论0 收藏0
  • 前端培训-初级阶段-场景实战2019-06-06)-Content-Type对照表及日常使用

    摘要:前端最基础的就是。数据被编码为键值对。大法好,精准识别,也算是正确的表单提交。全局的默认值实例默认值创建实例时设置配置的默认值在实例已创建后修改默认值拦截器,可以拦截错误,进行上报。参考资料类型看云 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水...

    张金宝 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<