您现在的位置是:首页 > 个人博客日记 个人博客日记

js实现图片上传预览原理

2016-01-01 09:29:46

js实现图片上传预览原理

现在网上有很多成熟的图片上传的插件,由于之前对于图片上传未接触过,不了解其实现原理。网上查阅了相关资料,了解到其是基于FileReader Api。

众所周知,大家平时做兼容性都是为了兼容低版本浏览器,图片上传则恰恰相反。基于浏览器的安全策略,file标签在现代浏览器中已经获取不到真实路径。恰恰相反,低版本ie却能获取到真实物理路径。所以此功能是基于现代浏览器的解决方案。

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

FileReader有四种读取文件的方式:

1. readAsBinaryString读取为二进制码

2. readAsDataURL读取为 DataURL

3. readAsText读取为文本

4. readAsArrayBuffer

基于预览上传后图片的需求,需要将图片读取为DataURL。DataURL有固定格式,例如:data:[文件格式];base64,[文本流base64编码]。

jpg格式:data:image/jpeg;base64,/9j/4…

png格式: data:image/png;base64,iVBORw…

gif格式:data:image/gif;base64,R0lGOD..

通过此格式我们就可以验证用户上传的图片类型。下面是本人写的简单demo:js实现图片上传预览原理现在网上有很多成熟的图片上传的插件,由于之前对于图片上传未接触过,不了解其实现原理。网上查阅了相关资料,了解到其是基于FileReader Api。众所周知,大家平时做兼容性都是为了兼容低版本浏览器,图片上传则恰恰相反。基于浏览器的安全策略,file标签在现代浏览器中已经获取不到真实路径。恰恰相反,低版本ie却能获取到真实物理路径。所以此功能是基于现代浏览器的解决方案。FileReader就是html5为我们提供的读取文件的api。它的作用就是把文本流按指定格式读取到缓存,以供js调用。FileReader有四种读取文件的方式:1. readAsBinaryString读取为二进制码2. readAsDataURL读取为 DataURL3. readAsText读取为文本4. readAsArrayBuffer基于预览上传后图片的需求,需要将图片读取为DataURL。DataURL有固定格式,例如:data:[文件格式];base64,[文本流base64编码]。jpg格式:data:image/jpeg;base64,/9j/4… png格式: data:image/png;base64,iVBORw…gif格式:data:image/gif;base64,R0lGOD..通过此格式我们就可以验证用户上传的图片类型。下面是本人写的简单demo:

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10.  <input id="files" type="file" onchange="previewImage(this, 'prvid')" multiple="multiple">
  11. <div id="prvid">预览容器</div>
  12. </body>
  13. </html>
  1. <script>
  2. function previewImage(file, prvid) {
  3. /* file:file控件 * prvid: 图片预览容器 */ var tip = "Expect jpg or png or gif!"; // 设定提示信息 var filters = {
  4. "jpeg" : "/9j/4",
  5. "gif" : "R0lGOD",
  6. "png" : "iVBORw" }
  7. var prvbox = document.getElementById(prvid);
  8. prvbox.innerHTML = "";
  9. if (window.FileReader) { // html5方案 for (var i=0, f; f = file.files[i]; i++) {
  10. var fr = new FileReader();
  11. fr.onload = function(e) {
  12. var src = e.target.result;
  13. if (!validateImg(src)) {
  14. alert(tip)
  15. } else {
  16. showPrvImg(src);
  17. }
  18. }
  19. fr.readAsDataURL(f);
  20. }
  21. } else { // 降级处理 if ( !/\.jpg$|\.png$|\.gif$/i.test(file.value) ) {
  22. alert(tip);
  23. } else {
  24. showPrvImg(file.value);
  25. }
  26. }
  27. function validateImg(data) {
  28. var pos = data.indexOf(",") + 1;
  29. for (var e in filters) {
  30. if (data.indexOf(filters[e]) === pos) {
  31. return e;
  32. }
  33. }
  34. return null;
  35. }
  36. function showPrvImg(src) {
  37. alert(src);
  38. var img = document.createElement("img");
  39. img.src = src;
  40. prvbox.appendChild(img);
  41. }
  42. }
  43. </script>


关注TinyMeng博客,更多精彩分享,敬请期待!
 

站点信息