如果你看了上一篇《ASP.NET 使用js插件出现上传较大文件失败的解决方法(ajaxfileupload.js第一弹)》的话,应该就知道我是逼不得已要认真学习下ajaxfileupload.js这个上传文件插件的。哈哈,开个玩笑啦,其实学习是给自己学的,而且学会了真的是很享受的~

这篇呢,就是想把这个插件的思路说一下,其中中文注解是我写的,英文注解应该是原作者写的吧~说实话,有些if判断里的东西我也没太弄明白,但是大致思路还是OK的。

jQuery.extend({createUploadIframe:function(id,uri){//id为当前系统时间字符串,uri是外部传入的json对象的一个参数//createframevarframeId='jUploadFrame'+id;//给iframe添加一个独一无二的idvariframeHtml='<iframeid="'+frameId+'"name="'+frameId+'"';//创建iframe元素if(window.ActiveXObject){//判断浏览器是否支持ActiveX控件if(typeofuri=='boolean'){iframeHtml+='src="'+'javascript:false'+'"';}elseif(typeofuri=='string'){iframeHtml+='src="'+uri+'"';}}iframeHtml+='/>';jQuery(iframeHtml).appendTo(document.body);//将动态iframe追加到body中returnjQuery('#'+frameId).get(0);//返回iframe对象},createUploadForm:function(id,fileElementId,data){//id为当前系统时间字符串,fileElementId为页面<inputtype='file'/>的id,data的值需要根据传入json的键来决定//createformvarformId='jUploadForm'+id;//给form添加一个独一无二的idvarfileId='jUploadFile'+id;//给<inputtype='file'/>添加一个独一无二的idvarform=jQuery('<formaction=""method="POST"name="'+formId+'"id="'+formId+'"enctype="multipart/form-data"></form>');//创建form元素if(data){//通常为falsefor(variindata){jQuery('<inputtype="hidden"name="'+i+'"value="'+data[i]+'"/>').appendTo(form);//根据data的内容,创建隐藏域,这部分我还不知道是什么时候用到。估计是传入json的时候,如果默认传一些参数的话要用到。}}varoldElement=jQuery('#'+fileElementId);//得到页面中的<inputtype='file'/>对象varnewElement=jQuery(oldElement).clone();//克隆页面中的<inputtype='file'/>对象jQuery(oldElement).attr('id',fileId);//修改原对象的idjQuery(oldElement).before(newElement);//在原对象前插入克隆对象jQuery(oldElement).appendTo(form);//把原对象插入到动态form的结尾处//setattributesjQuery(form).css('position','absolute');//给动态form添加样式,使其浮动起来,jQuery(form).css('top','-1200px');jQuery(form).css('left','-1200px');jQuery(form).appendTo('body');//把动态form插入到body中returnform;},ajaxFileUpload:function(s){//这里s是个json对象,传入一些ajax的参数//TODOintroduceglobalsettings,allowingtheclienttomodifythemforallrequests,notonlytimeouts=jQuery.extend({},jQuery.ajaxSettings,s);//此时的s对象是由jQuery.ajaxSettings和原s对象扩展后的对象varid=newDate().getTime();//取当前系统时间,目的是得到一个独一无二的数字varform=jQuery.createUploadForm(id,s.fileElementId,(typeof(s.data)=='undefined'?false:s.data));//创建动态formvario=jQuery.createUploadIframe(id,s.secureuri);//创建动态iframevarframeId='jUploadFrame'+id;//动态iframe的idvarformId='jUploadForm'+id;//动态form的id//Watchforanewsetofrequestsif(s.global&&!jQuery.active++){//当jQuery开始一个ajax请求时发生jQuery.event.trigger("ajaxStart");//触发ajaxStart方法}varrequestDone=false;//请求完成标志//Createtherequestobjectvarxml={};if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);//触发ajaxSend方法//WaitforaresponsetocomebackvaruploadCallback=function(isTimeout){//回调函数vario=document.getElementById(frameId);//得到iframe对象try{if(io.contentWindow){//动态iframe所在窗口对象是否存在xml.responseText=io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;xml.responseXML=io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;}elseif(io.contentDocument){//动态iframe的文档对象是否存在xml.responseText=io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;xml.responseXML=io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;}}catch(e){jQuery.handleError(s,xml,null,e);}if(xml||isTimeout=="timeout"){//xml变量被赋值或者isTimeout=="timeout"都表示请求发出,并且有响应requestDone=true;//请求完成varstatus;try{status=isTimeout!="timeout"?"success":"error";//如果不是“超时”,表示请求成功//Makesurethattherequestwassuccessfulornotmodifiedif(status!="error"){//processthedata(runsthexmlthroughhttpDataregardlessofcallback)vardata=jQuery.uploadHttpData(xml,s.dataType);//根据传送的type类型,返回json对象,此时返回的data就是后台操作后的返回结果//Ifalocalcallbackwasspecified,fireitandpassitthedataif(s.success)s.success(data,status);//执行上传成功的操作//Firetheglobalcallbackif(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}elsejQuery.handleError(s,xml,status);}catch(e){status="error";jQuery.handleError(s,xml,status,e);}//Therequestwascompletedif(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);//HandletheglobalAJAXcounterif(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");//Processresultif(s.complete)s.complete(xml,status);jQuery(io).unbind();//移除iframe的事件处理程序setTimeout(function(){//设置超时时间try{jQuery(io).remove();//移除动态iframejQuery(form).remove();//移除动态form}catch(e){jQuery.handleError(s,xml,null,e);}},100)xml=null}}//Timeoutcheckerif(s.timeout>0){//超时检测setTimeout(function(){//Checktoseeiftherequestisstillhappeningif(!requestDone)uploadCallback("timeout");//如果请求仍未完成,就发送超时信号},s.timeout);}try{varform=jQuery('#'+formId);jQuery(form).attr('action',s.url);//传入的ajax页面导向urljQuery(form).attr('method','POST');//设置提交表单方式jQuery(form).attr('target',frameId);//返回的目标iframe,就是创建的动态iframeif(form.encoding){//选择编码方式jQuery(form).attr('encoding','multipart/form-data');}else{jQuery(form).attr('enctype','multipart/form-data');}jQuery(form).submit();//提交form表单}catch(e){jQuery.handleError(s,xml,null,e);}jQuery('#'+frameId).load(uploadCallback);//ajax请求从服务器加载数据,同时传入回调函数return{abort:function(){}};},uploadHttpData:function(r,type){vardata=!type;data=type=="xml"||data?r.responseXML:r.responseText;//Ifthetypeis"script",evalitinglobalcontextif(type=="script")jQuery.globalEval(data);//GettheJavaScriptobject,ifJSONisused.if(type=="json")eval("data="+data);//evaluatescriptswithinhtmlif(type=="html")jQuery("<div>").html(data).evalScripts();returndata;}})

ajaxfileupload.js插件大致的思路就是如上所述,但是对于ajax来说,传值也是相当关键的部分,也就是传入的json对象里的键值对。

调用方法如下:

$.ajaxFileUpload({url:'../../XXXX/XXXX.aspx',//用于文件上传的服务器端请求地址secureuri:false,//一般设置为falsefileElementId:$("input#xxx").attr("id"),//文件上传控件的id属性<inputtype="file"id="file"name="file"/>注意,这里一定要有name值//$("form").serialize(),表单序列化。指把所有元素的ID,NAME等全部发过去dataType:'json',//返回值类型一般设置为jsoncomplete:function(){//只要完成即执行,最后执行},success:function(data,status)//服务器成功响应处理函数{if(typeof(data.error)!='undefined'){if(data.error!=''){if(data.error=="1001"){//这个error(错误码)是由自己定义的,根据后台返回的json对象的键值而判断}elseif(data.error=="1002"){}alert(data.msg);//同errorreturn;}else{alert(data.msg);}}/**这里就是做一些其他操作,比如把图片显示到某控件中去之类的。*/},error:function(data,status,e)//服务器响应失败处理函数{alert(e);}})

整个就是使用ajaxfileupload.js插件的大致方法。当然,明白其工作原理越透彻,我们也就能越好的去操作和使用它。

以上的分析希望对刚接触ajaxfileupload.js插件的朋友们有帮助。

还有最后一弹,如有感兴趣的朋友,请关注:

jQuery 自制上传头像插件-附带Demo实例(ajaxfileupload.js第三弹)


补充:

《jQuery 关于IE9上传文件无法进入后台原因及解决办法(ajaxfileupload.js第四弹)》