原文地址: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格式。

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编码格式如下:

 jpg格式如下:
data:image/jpeg;base64,/9j/4... png格式如下:
data:image/png;base64,iVBORw... gif格式如下:
data:image/gif;base64,R0lGOD...

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

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

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

 function previewImage(file, prvid) {
/* file:file控件
* prvid: 图片预览容器
*/
var tip = "Expect jpg or png or gif!"; // 设定提示信息
var filters = {
"jpeg" : "/9j/4",
"gif" : "R0lGOD",
"png" : "iVBORw"
}
var prvbox = document.getElementById(prvid);
prvbox.innerHTML = "";
if (window.FileReader) { // html5方案
for (var i=0, f; f = file.files[i]; i++) {
var fr = new FileReader();
fr.onload = function(e) {
var src = e.target.result;
if (!validateImg(src)) {
alert(tip)
} else {
showPrvImg(src);
}
}
fr.readAsDataURL(f);
}
} else { // 降级处理
if ( !/\.jpg$|\.png$|\.gif$/i.test(file.value) ) {
alert(tip);
} else {
showPrvImg(file.value);
}
} function validateImg(data) {
var pos = data.indexOf(",") + 1;
for (var e in filters) {
if (data.indexOf(filters[e]) === pos) {
return e;
}
}
return null;
} function showPrvImg(src) {
var img = document.createElement("img");
img.src = src;
prvbox.appendChild(img);
}
}

使用示例:

 <input id="files" type="file" onchange="previewImage(this, 'prvid')" multiple="multiple">
<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. 2017 FVDI2 ABRITES Commander with 18 Softwares FULL Version + FLY OBD Terminator + J2534 DrewTech Softwares

    Highlights of FVDI2 Abrites Commander Full Version: 1.Free update online. 2.This is full version FVD ...

  2. iview 之 穿梭框 transfer

    概述 双栏穿梭选择框,常用于将多个项目从一边移动到另一边. 说明 Transfer 组件主要基于以下四个 API 来使用: :data:总体数据,数组,每项为一个对象,且必须含有 key 值,组件基于 ...

  3. django 中间件记录所有请求及请求执行时间

    class LoggingMiddleware(object): def process_request(self, request): request.start_time = time.time( ...

  4. CentOS下MySQL的安装过程

    1 查看 CentOS 自带的 mysql 输入命令: rpm -qa | grep mysql 2 将自带的MySQL卸载了 输入命令: rpm -e --nodeps mysql-libs-5.1 ...

  5. 通过Jscript中@cc_on 语句识别IE浏览器及版本的代码

    激活条件编译支持. @cc_on 备注 @cc_on 语句激活脚本引擎中的条件编译. 强烈推荐在注释中使用 @cc_on 语句,以使不支持条件编译的浏览器将您的脚本视为有效语法而接受它: /*@cc_ ...

  6. unity状态机实现

    刚看了浅墨大神的文章让我对状态机有了进一步的理解 具体实现见装载的状态机文章 首先得有个总状态HeroineBaseState接口,其里面的方法主要是与行为相关的方法,让继承此接口的类来实现的 具体的 ...

  7. Tcp参数优化

    net.core.netdev_max_backlog = 400000 #该参数决定了,网络设备接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目. net.core.opt ...

  8. spring 3.0 整合redis

    参考文章:https://blog.csdn.net/weixin_42184707/article/details/80361464 其中遇到了问题,第一,redis的xml配置文件中的,头部地址资 ...

  9. 完整maven项目搭建

    1. 在eclipse中New选择maven项目,并选择web类型这个百度一下到处有: 2. 写简单的controller示例: 3. 配置web.xml,主要是DispatcherServlet: ...

  10. Linux中让普通用户拥有超级用户的权限

    问题 假设用户名为:ali 如果用户名没有超级用户权限,当输入 sudo + 命令 时, 系统提示: ali is not in the sudoers file.  This incident wi ...