上一篇文章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 } }
好了,基本效果已经完成并实现,至于样式还是自己弄吧,后端文件代码,我会在后面贴出来的,谢谢大家的捧场!多多指教