• 欢迎关注我的微信公众号“ frontEnd_Developer ” 右边扫描关注 --->>

基于HTML5 Ajax文件上传进度条实现方法(jquery版本)

Code Log 神棍 2160℃ 0评论

上一篇文章HTML5 AJAX 异步上传文件 中用到了FormData对象,这是HTML5新增加的一个的对象。

FormData 对象可以使用append 方法进行 key – value的数据添加,与以前我们常用的json不同的就是可以异步上传二进制文件。

首先是FormDate对象的创建:

var formData = new FormData();

向 FormDate 对象添加数据:

formData.append("catname", "我是一只喵");
formData.append("age", 1);         // 数字类型会转为字符串类型
// 可以增加上传的二进制文件,比如fileInputElement对象中已经包含了用户所选择的文件
formData.append("userfile", fileInputElement.files[0]);
//也可以将一个 Blob 对象添加到 formData 中
var oFileBody = "hey!"; 
var oBlob = new Blob([oFileBody], { type: "text/xml"});
formData.append("webmasterfile", oBlob);

使用 FormData 对象:

var xhr = new XMLHttpRequest();
xhr.open("POST", "upload");
xhr.send(formData);

FormData对象的使用基本就是这样的,接下来,我们看看HTML的结构吧

<form action="upload" method='post' enctype="multipart/form-data">
 <input type="hidden" value="upload" name="action" id="u_a">
 <a href="javascript:void(0)" class="file" id="files">选择文件
 <input type="file" name="u_file" accept="aplication/zip" id="u_file">
 </a>

 <div class="showFileName"></div>
 <a href="javascript:void(0)" class="file">上传
 <input type="button" value="上传" id="up">
 </a>
 <!-->进度条<--->
 <div class="progress">
 <div id="progress">
 <span> </span>
 </div>
 </div>
 <!-->提示<--->
 <div class="fileerrorTip alert"></div>
 </form>

接下来就是我们需要的重点内容了哦,JS部分,是使用了jQuery写的

首先,我们需要给file文件上传按钮,添加一个onchang事件

    $("#files").on("change", "input[type='file']", function () {
        varFile($(this).val())
    })

在看 uploadFile 方法之前,再让我们简单学习一下进度事件 (Progress Events )的progress 吧

Progress Events规范是W3C的一个工作草案,定义了与客户端服务器通信有关的事件。这些事件最早其实值针对XHR操作,但目前也被其它API借鉴。有以下6个进度事件。

loadstart:在接收到相应数据的第一个字节时触发。

progress:在接收相应期间持续不断触发。

error:在请求发生错误时触发。

abort:在因为调用abort()方法而终止链接时触发。

load:在接收到完整的相应数据时触发。

loadend:在通信完成或者触发error、abort或load事件后触发。

progress事件是Mozilla提交的,这个事件会在浏览器接收新数据期间周期性地触发。而onprogress事件处理程序会接收到一个event对象,其target属性是XHR对象,但包含着三个额外的属性:

lengthComputable :表示进度信息是否可用的布尔值

position :表示已经接收的字节数

totalSize :表示根据Content-Length相应头部确定的预期字节数。

有了这些信息,我们就可以为用户创建一个进度指示器了。但是 问题又来了, jQuery的 ajax 方法没有关于 progress 事件的操作。这怎么玩~~

好在通过查阅资料发现,jQuery的ajax方法调用的XMLHttpRequest对象是可以指定的!!!

该介绍的介绍完了,来我们看下核心代码吧

    var cot = true, file_Name = null, fileName;
    $("#up").click(function () {
        if (varFile()) {
            //console.log(fileName + '+'+ file_Name);
            if (fileName == file_Name) {
                alert('对不起,你所选择的文件已经上传,请从新选择!');
                return false
            }
            file_Name = fileName;
            var formData = new FormData();
            formData.append('action', $("#u_a").val());
            formData.append('u_file', $("#u_file")[0].files[0]);
            $.ajax({
                type: "POST",
                url: "upload.php",
                processData: false,
                contentType: false,
                data: formData,
                xhr:function(){
                    var xhr = $.ajaxSettings.xhr();
                    if(onprogress && xhr.upload) {
                        xhr.upload.addEventListener("progress" , onprogress, false);
                        return xhr;
                    }
                },
                success: function (msg) {
                    alert("Data Saved: " + msg);
                }
            });
            //方法为上传的进度条
            function onprogress(evt){
                var loaded = evt.loaded;     //已经上传大小情况
                var tot = evt.total;      //附件总大小
                var per = Math.floor(100*loaded/tot);  //已经上传的百分比
                if(per>2){
                    $('.progress').show();
                }
                $("#progress").css("width" , per +"%").find("span").html( per +"%");
            }
        } else {
            alert("只允许上传zip压缩文件!")
        }
    });

我这里只上允许上传zip的文件包,如果需要上传其他文件修改上传限制后缀即可!
下面是检验上传的文件类型

  function varFile(file) {
        //console.log(file)
        $('.progress').hide();
        var filePath = file || $("#files input").val();
        //console.log(filePath)
        var fileType = (filePath.substring(filePath.lastIndexOf(".") + 1, filePath.length)).toLowerCase();
        if (filePath.indexOf("zip") != -1 && fileType === 'zip') {
            $(".fileerrorTip").html("").hide();
            var arr = filePath.split('\');
            fileName = arr[arr.length - 1];
            $(".showFileName").html(fileName).css({padding: "4px 18px"});
            $("#files").css({borderRadius: "4px 0 0 4px"});
            return true
        } else {
            $(".showFileName").html("").css({padding: "0px"});
            $("#files").css({borderRadius: "4px"});
            $(".fileerrorTip").html("您未选择文件,或者您选择的文件类型有误!").show();
            return false
        }
    }

好了,基本效果已经完成并实现,至于样式还是自己弄吧,后端文件代码,我会在后面贴出来的,谢谢大家的捧场!多多指教

转载请注明:Falost的小窝 » 基于HTML5 Ajax文件上传进度条实现方法(jquery版本)

如果你觉得这篇文章不错或者对你有帮助,想请我喝一杯咖啡,可以打赏
喜欢 (38)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(4)个小伙伴在吐槽
  1. 为什么文件还没有上传完进度条就已经加载完成了,传大点的文件,100兆左右的就是进度条很快加载完了,但文件其实没有传完
    蓝天2017-09-12 16:57 回复
    • 如果正常代码上传是正常的,你所说的问题,应该不会发生,可以将代码贴上来看看!
      神棍2017-09-12 17:02 回复
  2. xhr.upload.addEventListener("progress" , onprogress, false); onprogress 不用跟参数?
    test2017-09-01 16:57 回复
    • 不需要的,在 onprogress 的时候会接收到这个event对象的
      神棍2017-09-01 17:04 回复