zoukankan      html  css  js  c++  java
  • JS上传图片-通过FileReader获取图片的base64

    下面文章,我想要的是:

    FileReader这个对象,可以借助FileReader来获取上传图片的base64,就可以在客户端显示该图片了。同时,还可以把该图片的base64发送到服务端,保存起来。

    在XMLHttpRequest Level2出台之前,大多数的异步上传图片都是利用iframe去实现的。

     
    至于具体的实现细节,我就不在这边啰嗦的,Google一下就有文章谈这个东西。
     
    这次主要说说,怎么用新的API去实现图片上传。
     
     
    原标题:JavaScript怎么上传图片
     
    首先,少不了的自然是XMLHttpRequest Level2的一些新特性啦。
     
    其中最为实在的就是FormData对象,直接把表单(form)的Dom对象转为FormData对象,然后向服务器发送。
     
    还有就是Progress事件的支持,异步上传终于可以查看进度条啦!
     
    这里我就不废话了,因为大多数人应该都看过的 阮一峰 的 《XMLHttpRequest Level 2 使用指南》,直接贴代码吧。
     
    1 var formData= new FormData(form),
    2     xhr= new XMLHttpRequest();
    4 xhr.open("POST", url);
    5 xhr.send(formData);    
    接口的部分也很简单,例如PHP,直接用$_POST、$_FILES就可以拿到相关的数据.
     
    没错,就是这么简单。
     
    而通过监听Progress时间,就可以判断当前数据上传/下载的进度。
     
     
    1 xhr.upload.onprogress = function (e) {
    2     console.log(e.loaded / e.total * 100);    // 上传进度
    3 }
    5 xhr.onprogress = function (e) {
    6     console.log(e.loaded / e.total * 100);    //  下载进度
    7 }
     
    至于XMLHttpRequest Level2的支持情况,在移动端还是比较理想的。
     
     
     
     
     
     
    一直以来,无数的前端屌丝都渴望浏览器可以提供JavaScript访问本地文件的API。
     
    其实大老早,IE就能利用ActiveX来操作本地文件了,但因为并非W3C的标准,一直就只有IE在玩。
     
    于25 October 2012,W3C订立了File API的草案。
     
    另外,和File对象配套使用的,还有FileReader对象。具体有什么用后面再说。
     
    下面是它们俩的支持度,情况比较一般。不过先学着就差不多了,哈~
     
     
     
     
    先说说File对象吧。
     
    File对象是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以是来自由拖放操作生成的 DataTransfer对象.
     
    如下:
     
     
    1 // input:file的File对象
    2 document.querySelector("input[type=file]").files;    // return FileList
    4 // drop事件的File对象
    5 elem.ondrop = function (e) {
    6     e.preventDefault();
    7     return e.dataTransfer.files;     // return FileList
    8 };
     
    都是以一个FileList的对象返回。这个FileList的对象类似于NodeList。有length属性,但并非数组。
     
    下面是Chrome Console打印出来的FileList对象:
     
     
     
    再看看File对象有什么属性:
     
     
     
    那些属性都代表什么意思我就不再废话了。但我们可以留意到,File对象是继承于Blob对象,至于什么是Blob对象,后面的篇幅咱们再提及。
     
     
     
    一开始,我们还提到一个FileReader的对象,说是配套着File对象一起用。
     
    使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要读取的文件或数据.
     
    具体怎么用,我们看看下面的代码:
     
     
     1 // 创建一个FileReader对象
     2 var reader = new FileReader();
     3 
     4 // 绑定load事件
     5 reader.onload = function(e) {
     6     console.log(e.target.result);
     7 }
     8 
     9 // 读取File对象的数据
    10 reader.readAsDataURL(document.querySelector("input[type=file]").files[0]);
     
    当FileReader对象通过readAsDataURL读取数据成功后,就会触发load事件。target中的result属性的值,就是该文件的base64数据
     
     
     
     
     
    当然,FileReader对象不单单只有readAsDataURL一个方法。
     
     
     1 /**
     2  * 中止该读取操作.在返回时,readyState属性的值为DONE.
     3  */
     4 reader.abort();
     5 
     6 
     7 /**
     8  * 开始读取指定的Blob对象或File对象中的内容. 
     9  * 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.
    10  * 同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.
    11  */
    12 reader.readAsDataURL(file);
    13 
    14 
    15 /**
    16  * 同上, result属性中将包含一个字符串以表示所读取的文件内容.
    17  * encoding是可选项,类型为字符串,表示了返回数据所使用的编码.如果不指定,默认为UTF-8.
    18  */
    19 reader.readAsText(file[, encoding ]);
    20 
    21 
    22 /**
    23  * 同上, result属性中将包含一个ArrayBuffer对象以表示所读取文件的内容.
    24  */
    25 reader.readAsArrayBuffer(file); 
    26 
    27 
    28 /**
    29  * 同上, result属性中将包含所读取文件的原始二进制数据.
    30  */
    31 reader.readAsBinaryString(file);
     
     
     
    既然拿到了文件的base64,那做事情就方便多了。
     
    例如,我们可以直接把base64的字符串post到服务器端。
     
     
     1 var reader = new FileReader();
     2 
     3 reader.onload = function(e) {
     4     var xhr = new XMLHttpRequest(),
     5         fromData = new FormData();
     6 
     7     fromData.append("base64", e.target.result);
     8     xhr.open("post",url, true);
     9     xhr.send(fromData);
    10 }
    11 
    12 reader.readAsDataURL(document.querySelector("input[type=file]").files[0]);
     
    是不是觉得有什么不对?
     
    既然都用FormData了,还转个毛线base64啊!
     
     
     
    转成base64之后,最大的好处就是可以绘制到Canvas上,然后对图片进行编辑!
     
    在客户端这边做裁剪啊涂鸦啊什么的,编辑完成后再利用Canvas对象的toDataURL方法,就可以输出编辑后图片的base64数据。
     
    细节的实现我这里就不说了。
     
     
     
    我们再看看HTML5的file表单元素提供了什么新的支持:
     
    1 <input type="file" accept="image/*" id="file_image" name="file_image" multiple />
    2 <input type="file" accept="video/*" id="file_video" name="file_video" />
    accept属性,可以用来限制用户上传文件的类型。这个属性IOS和OSX支持得很好。
     
    另外还有multiple属性,意思就是可以选择多个文件。添加了这个属性之后,再配合FormData对象,可以实现批量上传。
     
     
     1 (function (W, D) {
     2     var fileForm = document.getElementById("file_form"),
     3         fileImage = document.getElementById("file_image");
     4 
     5     function testAjax(files, i) {
     6         if (i < 0) {
     7             return ;
     8         }
     9 
    10         var xhr = new XMLHttpRequest(),
    11             data = new FormData();
    12 
    13         xhr.onload = function () {
    14             // 递归
    15             testAjax(files, --i);
    16         };
    17         data.append("file_image", files[i]);
    18         xhr.open("post", "test/demo2.php", true);
    19         xhr.send(data);
    20     }
    21 
    22     fileForm.addEventListener("submit", function (e) {
    23         e.preventDefault();
    24         var files = fileImage.files;
    25 
    26         testAjax(files, --files.length);
    27     }, false);
    28 
    29 })(window, document);
     
    来源:
    http://www.2cto.com/kf/201309/240742.html
  • 相关阅读:
    SharePoint 2013 图文开发系列之自定义字段
    SharePoint 2013 图文开发系列之Visual Studio 创建母版页
    SharePoint 2013 图文开发系列之代码定义列表
    SharePoint 2013 图文开发系列之计时器任务
    SharePoint 2013 图文开发系列之应用程序页
    SharePoint 2013 图文开发系列之事件接收器
    SharePoint 2013 图文开发系列之可视化WebPart
    SharePoint 2013 图文开发系列之WebPart
    SharePoint 2013 对二进制大型对象(BLOB)进行爬网
    SharePoint 2013 状态机工作流之日常报销示例
  • 原文地址:https://www.cnblogs.com/simonbaker/p/4667849.html
Copyright © 2011-2022 走看看