原文地址:http://www.2cto.com/kf/201401/274752.html

一、要解决什么样的问题?

在写这个函数之前,有们童鞋在群里问如何纯前端严格验证图片格式。这在html5时代之前,那是不可能实现的,必须要上传到后台,由后台脚本读取文本流后进一步验证。这样就造成了一定的服务器资源浪费。但是html5时代,这个工作我们完全可以交给前端来做了。

另一方面,html5时代,许多我们原来的图片预览方案都失效了。究其原因,其实是现代浏览器出于对用户隐私的保护,file控件不再提供真实的物理地址,而统一变成:C:\fakepath\xxx.xxx 这样的假地址。不过,天无绝人之路,虽然旧的方案失效了,但是html5还是给我们提供了其它的途径的。

那么,以上的问题我们该怎么解决呢?这就要借助html5提供的File API了。这里我们需要要用到的API是“ FileReader ”。

二、关于FileReader

顾名思义,FileReader就是html5为我们提供的读取文件的api。它的作用就是把文本流按指定格式读取到缓存,以供js调用。

FileReader有四种读取文件的方式,四种方式的区别如下:
1. readAsBinaryString ---- 将文件读取为二进制码

2. readAsDataURL ---- 将文件读取为 DataURL

3. readAsText ---- 将文件读取为文本

4. readAsArrayBuffer ----将文件读取为ArrayBuffer

因为还要做图片预览,所以我们这里将采用第二种readAsDataURL方式来读取文件。那么DataURL究竟是怎么样的一种格式呢?以下是截取的一个gif图片的DataURL格式。

  1. data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH...oJCAcGBQQDAgEAACH5BAEAAAAALAAAAAABAAEAQAICRAEAOw==

所谓的DataURL格式,其实就是:data:[文件格式];base64,[文本流base64编码]

这种格式有什么好处呢?对于前端来说,最直观的好处就是,可以把它写进img标签的src,也可以写进css的background-image。这样就可以把一张图片直接塞进html代码或者css代码中,而不必再多一次http request。

讲到这里,很多童鞋或许已经对有点眉目了,接着往下看。

三、图片格式验证方案

做过后台验证文件格式的童鞋应该知道,许多文件格式,是有固定的文件头的(文件的文本流开头几个字节)。我们的JPEG、GIF、PNG等图片,也有这样的文件头。所以,我们现在就是要通过这个文件头来对图片格式进行严格验证,就在前端,纯JS,不需要借助任何后台脚本的帮助。

刚刚说到,readAsDataURL方式读取的文件,会得到文件文本流的base64编码。所以,我们其实只需要对比一下base64编码的头几个字符就可以知道我们将要上传的文件格式是什么样的。经过我的多次验证,JPEG、GIF、PNG的DataURL编码格式如下:

  1. jpg格式如下:
  2. data:image/jpeg;base64,/9j/4...
  3.  
  4. png格式如下:
  5. data:image/png;base64,iVBORw...
  6.  
  7. gif格式如下:
  8. data:image/gif;base64,R0lGOD...

也就是说,jpeg图片的base64编码开头总是/9j/4,png的开头总是iVBORw,而gif的开头总是R0lGOD。所以,至此,我们的验证方案其实已经浮出水面了。

四、图片上传预览及验证函数

下面是综合上面说的所有知识我自己写的一个函数,在此提供给大家:

  1. function previewImage(file, prvid) {
  2. /* file:file控件
  3. * prvid: 图片预览容器
  4. */
  5. var tip = "Expect jpg or png or gif!"; // 设定提示信息
  6. var filters = {
  7. "jpeg" : "/9j/4",
  8. "gif" : "R0lGOD",
  9. "png" : "iVBORw"
  10. }
  11. var prvbox = document.getElementById(prvid);
  12. prvbox.innerHTML = "";
  13. if (window.FileReader) { // html5方案
  14. for (var i=0, f; f = file.files[i]; i++) {
  15. var fr = new FileReader();
  16. fr.onload = function(e) {
  17. var src = e.target.result;
  18. if (!validateImg(src)) {
  19. alert(tip)
  20. } else {
  21. showPrvImg(src);
  22. }
  23. }
  24. fr.readAsDataURL(f);
  25. }
  26. } else { // 降级处理
  27. if ( !/\.jpg$|\.png$|\.gif$/i.test(file.value) ) {
  28. alert(tip);
  29. } else {
  30. showPrvImg(file.value);
  31. }
  32. }
  33.  
  34. function validateImg(data) {
  35. var pos = data.indexOf(",") + 1;
  36. for (var e in filters) {
  37. if (data.indexOf(filters[e]) === pos) {
  38. return e;
  39. }
  40. }
  41. return null;
  42. }
  43.  
  44. function showPrvImg(src) {
  45. var img = document.createElement("img");
  46. img.src = src;
  47. prvbox.appendChild(img);
  48. }
  49. }

使用示例:

  1. <input id="files" type="file" onchange="previewImage(this, 'prvid')" multiple="multiple">
  2. <div id="prvid">预览容器</div>

五、兼容性

本函数兼容chrome、firefox、ie6+ 。 但由于ie9以下的浏览器并不支持FileReader,所以,在验证图片格式的时候,会有一个降级处理。


HTML5时代的纯前端上传图片预览及严格图片格式验证函数(转载)的更多相关文章

  1. 利用html5 canvas实现纯前端上传图片的裁剪

    今天跟大家分享一个前端裁剪图片的方法.许多网站都有设置用户头像的功能,用户可以选择一张本地的图片,然后用网站的裁剪工具进行裁剪,然后设置大小,位置合适的头像.当然,网上也有一些用js写的诸如此类裁剪的 ...

  2. 【小月博客】用HTML5的File API做上传图片预览功能

    前段时间做了一个项目,涉及到上传本地图片以及预览的功能,正好之前了解过 html5(点击查看更多关于web前端的有关资源) 可以上传本地图片,然后再网上看了一些demo结合自己的需求,终于搞定了.(P ...

  3. HTML5 上传图片预览

    html5出现之前如果需要上传图片预览 一般都是先上传到服务器然后远程预览 html5出现之后   有个filereader 解决了这问题 //选中图片之后 $("#fileAddPic&q ...

  4. HTML5上传图片预览

    <!DOCTYPE html> <html> <head> <title>HTML5上传图片预览</title> <meta http ...

  5. jquery实现上传图片预览(需要浏览器支持html5)

    jquery实现上传图片预览(需要浏览器支持html5) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...

  6. HTML5上传图片预览功能

    HTML5上传图片预览功能 HTML代码如下: <!-- date: 2018-04-27 14:41:35 author: 王召波 descride: HTML5上传图片预览功能 --> ...

  7. 通过HTML5 FileReader实现上传图片预览功能

    原文:http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201706224590.html 在上传图片到服务器之前,我们希望可以预览一下要上传的图片. ...

  8. HTML5文件上传前本地预览

    HTML5之FileReader的使用 HTML5定义了FileReader作为文件API的重要成员用于读取文件,根据W3C的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型 ...

  9. java多图片上传--前端实现预览--图片压缩 、图片缩放,区域裁剪,水印,旋转,保持比例。

    java多图片上传--前端实现预览 前端代码: https://pan.baidu.com/s/1cqKbmjBSXOhFX4HR1XGkyQ 解压后: java后台: <!--文件上传--&g ...

随机推荐

  1. 4.nginx高可用

    1.大体结构 一.使用场景介绍: nginx做负载均衡,来达到分发请求的目的,但是不能很好的避免单点故障,假如nginx服务器挂点了,那么所有的服务也会跟着瘫痪 .keepalived+nginx,就 ...

  2. Duilib总体框架

    从GoogleCode上下载的duilib工程中附带的一副总体设计图(如下所示),可以先整体了解一下,有个初步的认识,对后续进一步深入了解学习会很有帮助. 通过设计图有了一个初步认识后,接下来开始进一 ...

  3. VUE安装步骤

    项目构建 项目推荐直接使用 Vue 官方提供的脚手架(Vue-cli),所以第一步首先是安装脚手架.在命令行或者 IDE 的 Terminal 窗口中输入以下命令即可自动安装: npm install ...

  4. win10操作系统系统,小米路由器,小米3 的问题

    注意 , 置顶 单独一篇 : { win10  局域网共享 小米路由器,操作盘太卡 } 开发中用专业版 , 别用家庭版 比如有远程桌面程序 和 HV 虚拟机 查看激活信息 和 是不是永久激活 参考 h ...

  5. 文件IO(存取.txt文件)

    //存文件方法 public void Save_File_Info(string Save_Path) { //根据路径,创建文件和数据流 FileStream FS = new FileStrea ...

  6. js函数声明提升与变量提升

    变量提升 变量提升: 在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性” 提升到当前作用域的顶部,其值为 undefined ,没有 “可用性”. alert(a); // ...

  7. JavaScript跨浏览器处理事件以及相关对象

    主流的浏览器和IE浏览器在处理事件和事件对象上是有所区别的,我们一般会通过EventUtil进行封装,这样,就可以正常的跨浏览器处理事件了,本文的主要内容总结自<JavaScript高级程序设计 ...

  8. 常用工具说明--Git和GitHub简明教程

    一.Git的主要功能:版本控制 版本:想想你平时用的软件,在软件升级之后,你用的就是新版本的软件.你应该见过这样的版本号:v2.0 或者 1511(表示发布时为15年11月),如下图:那么如果你修改并 ...

  9. 将forme表单转换为Json对象

    //将Form 表单转换为Json字符串 $.fn.serializeObject = function () { var o = {}; var a = this.serializeArray(); ...

  10. 【request获取用户请求ip】

    1:request.getRemoteAddr() 2:如果请求的客户端使用了nginx 等反向代理发送请求的时候:就不能获取到真是的ip地址了:如:将http://192.168.1.110:204 ...