一、引言

  继上次实现文件上传功能后,产品经理又提出了新的需求:上传图片预览及进度条效果。本次就来搞定这个功能,这次开发基于上次的随笔,需要的小伙伴们自取 -- 如何使用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>

  文件对象信息打印如下:

如何使用 Ajax 实现上传图片时预览及上传进度效果

  图片预览效果图:

如何使用 Ajax 实现上传图片时预览及上传进度效果

  由于本地上传比较快,图片太小了看不出效果,我特意选了张50M的图片,或者大家使用Chrome的网络工具将网速调慢进行测试:

如何使用 Ajax 实现上传图片时预览及上传进度效果

如何使用 Ajax 实现上传图片时预览及上传进度效果

四、总结

  基本功能算是实现了,UI还可以优化一下,大家也可以自己花点功夫将图片上传功能完善,添加大图预览等功能,然后封装成一个控件供以后使用。

发表回复