如何使用 Ajax 实现上传图片时预览及上传进度效果
一、引言
继上次实现文件上传功能后,产品经理又提出了新的需求:上传图片预览及进度条效果。本次就来搞定这个功能,这次开发基于上次的随笔,需要的小伙伴们自取 -- 如何使用Ajax实现简单的文件上传。
二、了解原理
要想实现文件预览效果,这里使用的是 FileReader 对象。使用它的 readAsDataURL 方法将图片内容转化为URL格式的Base64字符串,然后就可以在其onload事件中用src属性将图片渲染到页面进行预览了。
要想实现文件上传进度效果,这里使用的是xhr(XMLHttpRequest)的 progress 事件。在此方法中我们可以获取到文件的总大小以及已经发送的大小,进而计算得到上传的百分比。
理论存在,开始实践!
三、编码测试
在上次的Demo基础上对页面进行了一些调整,代码如下:
<div> <input id="upload" type="file" multiple style="display: none;" /> <input id="bt1" type="button" value="点击选择" /> <input id="bt2" type="button" value="打印对象" /> <input id="bt3" type="button" value="加载预览" /> <input id="bt4" type="button" value="开始上传" /> <span>上传进度:</span><span id="prog">0%</span> <br /> <div id="div1" style="height: 200px;"></div> </div> <script type="text/javascript"> $(function () { var upload = $("#upload"); $("#bt1").on('click', function () { upload.click(); }); $("#bt2").on('click', function () { console.log(upload[0].files); }); $("#bt3").on('click', function () { var div = $("#div1"); for (var i = 0; i < upload[0].files.length; i++) { var reader = new FileReader(); reader.readAsDataURL(upload[0].files[i]); //依次读取图片 reader.onload = function (e) { //读取完毕回调 var img = $("<img width='200' height='200' >").attr('src', e.target.result); div.append(img); //将其追加到页面上 } } }); $("#bt4").on('click', function () { var formdata = new FormData(); for (var i = 0; i < upload[0].files.length; i++) { formdata.append('pic', upload[0].files[i]); } $.ajax({ type: "post", url: "Default/Upload", data: formdata, contentType: false, processData: false, success: function (data) { console.log("success!"); }, error: function () { console.error("error!"); }, xhr: function () { var myXhr = $.ajaxSettings.xhr(); if (myXhr.upload) { //检查upload属性是否存在 myXhr.upload.addEventListener('progress', progressHandlingFunction, false); //绑定progress事件的回调函数 } return myXhr; //xhr对象返回给jQuery使用 } }); function progressHandlingFunction(event) { var loaded = Math.floor(100 * (event.loaded / event.total)); //计算已经上传的百分比 $("#prog").html(loaded + "%"); //应用到显示UI,可根据自己需要修改 } }); }) </script>
文件对象信息打印如下:
图片预览效果图:
由于本地上传比较快,图片太小了看不出效果,我特意选了张50M的图片,或者大家使用Chrome的网络工具将网速调慢进行测试:
四、总结
基本功能算是实现了,UI还可以优化一下,大家也可以自己花点功夫将图片上传功能完善,添加大图预览等功能,然后封装成一个控件供以后使用。