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

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

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


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


2. 一个朋友的问题,下载的文件需要 headers 验证,无奈只能 ajax 拿数据。


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


今天我们要讲什么?


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


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


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


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


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


下载文件,并显示进度条


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


显示进度条


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


  1. ajax 实现下载进度条,测试地址-显示进度条
xhr = new XMLHttpRequest();
xhr.open('get', file1.url);
xhr.onprogress = (e)=>console.log(e)//e 就是一个 ProgressEvent 对象,其中 loaded 是已下载的, total 是总大小。
xhr.send()


2.fetch 实现下载进度条,测试地址-fetch显示进度条并下载


fetch 的实现上来说有一些功能是没有的,比如 abort、进度等。那我们就需要去通过一些别的手段来模拟实现。


实现代码如下,我们操作成读流,然后统计长度。


bVbtb2M.webp.jpg


下载文件


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

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


4110456011-5cec8a644e222_fix732.png


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


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

971268328-5cec8ac85d8ad.png


   b.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)// 异步的,所以需要回调里面拿


 bVbtb5k.webp.jpg


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


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


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


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


  1. 浏览器缓存
    我比较推荐用这个,因为其他的方案都有大小或者兼容上的问题。但是这个缓存需要服务器设置需要走缓存。
  2. bloburl 本地缓存下载
    这个方案在移动端异常,pc端正常,感兴趣的小伙伴可以自己实现一下,毕竟学了这么多,得用起来才能变成自己的
  3. 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 来读取


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


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

bVbtcnI.webp.jpg


2.blob to DataURLreadAsDataURL


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

bVbtcn5.webp.jpg

3.blob to TextreadAsText


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


bVbtcox.webp.jpg


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


bVbtcoE.webp.jpg


* to blob


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


  1. 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


1305284727-5cecc605eb7aa_fix732.png


3.BinaryString to blob


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


4.Text to blob


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


view.webp (7).jpg

总结


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


base64转换上传,也写过这样的。


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


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


后记


参考资料


  1. Data URLs --MDN
  2. StringView
  3. 字符编码中ASCII、Unicode和UTF-8的区别
  4. String.prototype.charCodeAt()
  5. DOMString
  6. rfc2397
相关文章
|
2月前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
133 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
1月前
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
80 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
13天前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
1月前
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
54 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
3月前
|
存储 前端开发 JavaScript
前端状态管理:Vuex 核心概念与实战
Vuex 是 Vue.js 应用程序的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。本教程将深入讲解 Vuex 的核心概念,如 State、Getter、Mutation 和 Action,并通过实战案例帮助开发者掌握在项目中有效使用 Vuex 的技巧。
|
4月前
|
Web App开发 缓存 监控
前端性能优化实战:从代码到部署的全面策略
前端性能优化实战:从代码到部署的全面策略
67 1
|
4月前
|
缓存 监控 前端开发
前端性能优化实战:从加载速度到用户体验
前端性能优化实战:从加载速度到用户体验
|
5月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
416 14
|
5月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
94 0
|
5月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
146 6

热门文章

最新文章