这里是《整理前端开发中的可复用代码》中的第二篇,最初此系列文章的标题不是这个,但觉得标题要准确、明白一些,便做了修改。这里的经验都来自作者的工作实践,入了前端坑的摸爬滚打。

背景

在工作中接到一个需求,需要在浏览器端计算文件的md5值,然后在上传文件时传递给后端储存。按照以往的思路,后端只需要三两行代码即可实现,比如使用php中的md5_file。

<?php$filename = "file.jpg";$md5 = md5_file($filename);echo $md5;
?>
复制代码

然而文件并不是上传到后端服务器,而是直接上传到阿里云的oss。如果后端去请求oss上的文件计算md5,就容易造成服务器的压力,所以计算文件md5的最好方式是交给客户端实现。

尽管以前没有接触过浏览器端计算文件md5,但在谷歌、百度搜索一番后,便用spark-md5解决了这一需求。但如果事情就这样结束了的话,就没有后续计算网络文件md5的想法,以及这篇文章的出现了。

接着计算本地文件md5的需求,又接到了一个需求。上传的图片要进行压缩,压缩使用plupload的自带功能实现,而压缩后的图片md5已改变。经过一些时间还没有找到解决方案,加上技术总监对我说项目后续要增加新东西,让我最好在审核上传资源的时候计算md5,这样便开始了前端计算网络文件md5的摸索。

File 对象

在谷歌、百度了N久之后,没有找到一个准确的答案,包括flash方案。我想应该很少有在浏览器端计算网络文件md5的需求或实现,也展开了自己的一些猜想。

第一应该先要有一个文件,然后从文件中计算md5,类似:

var file = new File(['www.domain.com/test.jpg'], 'test.jpg', {type: 'image/jpg'});
复制代码

然而File对象并不接收url参数来生成文件,这里的url被当成字符串处理了,这不是想要的答案。

Blob 对象

Blob对象是一个类文件对象,File对象继承于Blob对象,它们的用法类似,Blob也不能直接处理url为Blob对象。但要计算文件md5,需要FileReader读取一个File或Blob对象,再由spark-md5进一步计算得出md5。

所幸在XMLHttpRequest中可以指定responseType为blod,请求文件并指定responseType为blod时,XMLHttpRequest将返回一个Blob对象,相关介绍可参考这里responseType,如下:

var request = new XMLHttpRequest();request.open('GET', url, true);
request.responseType = 'blob';
request.onload = function() {//类似Blob(3275) {size: 3275, type: "image/vnd.microsoft.icon"}console.log(request.response);
};
request.send();
复制代码

至此,下一步便可以用spark-md5计算Blob对象来返回md5了(spark-md5官方示例)。

var request = new XMLHttpRequest();request.open('GET', url, true);
request.responseType = 'blob';
request.onload = function() {var file = request.response;var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,chunkSize = 2097152, // Read in chunks of 2MBchunks = Math.ceil(file.size / chunkSize),currentChunk = 0,spark = new SparkMD5.ArrayBuffer(),fileReader = new FileReader();fileReader.onload = function (e) {spark.append(e.target.result);currentChunk++;if (currentChunk < chunks) {loadNext();} else {//获取md5var md5 = spark.end();console.log(md5);}
};fileReader.onerror = function () {console.error('文件读取失败');
};function loadNext() {var start = currentChunk * chunkSize,end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
}loadNext();
};
request.send();
复制代码

拓展spark-md5

通过上面的代码,便实现了浏览器端js计算网络文件的md5。而据spark-md5的使用方式,直接计算字符串md5时比较简单:

SparkMD5.hash('hello world');//"5eb63bbbe01eeed093cb22bb8f5acdc3"
复制代码

如上只需要一行代码即可,但在计算文件时略复杂些,代码不利于复用。出于本系列文章整理可复用代码的初衷,以及想要加入计算网络文件md5功能,便封装了一个插件。

  • github地址:md5-util
  • 演示:md5-util demo,下方附二维码

使用方式:

<script src="md5-util.min.js"></script>
复制代码
//计算本地文件md5
SparkMD5.file(file,function(md5){console.log(md5)
})//计算网络文件md5
SparkMD5.file(url,function(md5){console.log(md5)
})
复制代码

这里参考过browser-md5-file,不同的是此插件只扩展了spark-md5,增加了file方法,spark-md5的所有方法均可在插件中使用。

浏览器兼容性

这里只讨论计算网络文件md5的兼容性,在pc端一些主流浏览器中测试了多次,得出的md5均是正确的。但由于XMLHttpRequest的responseType指定为blob,在移动端发现一些兼容性问题,已知ios uc浏览器及安卓5.1.1系统浏览器中返回blob异常,导致md5计算错误。

所以要计算网络文件的md5时,请慎用。如果哪位大神有更好的解决办法,还请分享下。

后记

一直以来web端计算md5的任务主要分配给后端,但渐渐的前端技术也能实现了,这意味着前端技术的逐渐繁荣。不过用“痛并快乐着”很适合描述前端开发,使用一个个新技术完成了以前不能实现的功能,也面临着各种浏览器兼容性问题带来的困扰。

还愿我们心怀向往,并砥砺前行吧。

此系列相关文章(同步更新):

  1. 整理前端工作中的可复用代码(一):做一个整合存储的插件
  2. 整理前端工作中的可复用代码(二):拓展spark-md5,支持计算网络文件md5

整理前端工作中的可复用代码(二):拓展spark-md5,支持计算网络文件md5相关推荐

  1. web前端学习中CSS,JS代码压缩

    web前端要学习的知识有很多,前端基础要学习三个部分:HTML,CSS,JavaScript(简称JS),因此首先明确三个概念:HTML负责结构,网页想要表达的内容由html书写. CSS负责样式,网 ...

  2. 前端面试中浏览器相关问题(二):回流与重绘

    前端面试中浏览器相关问题(二):回流与重绘 文章目录 前端面试中浏览器相关问题(二):回流与重绘 浏览器的渲染过程 生成渲染树 回流 重绘 何时发生回流重绘 浏览器的优化机制 减少回流和重绘 最小化重 ...

  3. 前端页面中根据链接随机生成二维码

    前端页面中根据链接随机生成二维码 1.需要安装qrcodejs2 npm install qrcodejs2 -save 2.在所需要的页面中引入 import QRCode from 'qrcode ...

  4. 阿里面试官:你在工作中是如何做代码重构的?

    我是猿人,一个热爱技术.热爱编程的IT猿.技术是开源的,知识是共享的! 写作是对自己学习的总结和记录,如果您对 Java.分布式.微服务.中间件.Spring Boot.Spring Cloud等技术 ...

  5. 前端通过spark-md5.js计算本地文件md5

    背景: 说到本人第一次使用spark-md5.js还是差不多一年以前的时候了,当时后台老大说要搞一个文件分片上传的功能.我当时就心想:what?啥是文件分片上传,完全没听过好吗? 至于我当时内心那个慌 ...

  6. jsp中 input placeholder_前端工作中的方法总结

    /*移动适配*/ <meta name="viewport" content="width=device-width, initial-scale=1,user-s ...

  7. 分享个人收集或整理的word中常用的vba代码

    在word中通过VBA编写一些常用的函数,再利用快捷键激发,可以有效的提高写作的效率.以下分享个人通过网络收集,或者改造,或者自己录制后修改的代码,有需要的可以自取. 因为已经记不清有些代码的出处了, ...

  8. web前端——工作中遇到的问题总结

    1.鼠标移动到input标签上面,提示:请输入有效值,两个最接近的有效值分别为x和x. 原因:当input的type属性为number时,输入框中的值为小数,就会出现该问题. 解决办法:<inp ...

  9. web前端工作笔记008---js延迟执行代码

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 setTimeout( function(){//add your code}, 5 * 1000 ...

最新文章

  1. php 输出图片给js,如何在php中利用croppic.js对图片进行剪切并上传
  2. 相机小景深和大景深的区别?
  3. AcWing - 171 送礼物(双向dfs)
  4. Oracle完全手册,Oracle_11g+Oracle Sqldeveloper 安装完全手册(for win 7 64x)
  5. 实验7.1 对Point类重载“++”(自增)、“–”(自减)运算符
  6. Hadoop学习曲线图
  7. 2017-2018-1 20155229 实验五 《通讯协议设计》
  8. D. Powerful array 莫队算法或者说块状数组 其实都是有点优化的暴力
  9. OA系统选型,明确需求是关键
  10. 简单家乡风景静态HTML网页设计作品 DIV布局家乡介绍网页模板代码
  11. GWAS 总体流程理解版
  12. linux gtx驱动程序,NVIDIA 430.09 Linux 驱动发布:支持 GTX 1650
  13. 用frp开源工具,实现内网穿透(详细教程)
  14. web前端面试题之魂(js)
  15. 自然语言处理与模型评价
  16. 十个高质量自学网站,让你的技术突飞猛进
  17. android 基础培训ppt,Android基础之内部培训.ppt
  18. 中高级JAVA工程师-面试题汇总
  19. 亚马逊 CTO 预测2021:八大技术趋势改变世界
  20. 联通3G 网络设置+彩信设置

热门文章

  1. 全球及中国沼气发电行业现状及项目发展动态调研报告2021年版
  2. 中国镍氢电池行业产销状况及竞争格局咨询报告2021-2027年版
  3. 中国电动汽车用电机行业发展模式分析及竞争战略研究报告2022-2028年版
  4. Day 6:Vector类和实现Hashset以及登录窗口的模拟
  5. 对象的克隆(clone方法)
  6. mysqldump: command not found
  7. javaweb学习总结十七(web应用组织结构、web.xml作用以及配置虚拟主机搭建网站)
  8. TCP连接之未连接队列的理解[转]
  9. 青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 3
  10. 互相封杀8年后,阿里终于挖开腾讯12亿流量金矿?