首页 > 代码库 > ajax图片单个上传(ajaxfileupload.js)

ajax图片单个上传(ajaxfileupload.js)

开发过程中发现,页面总是只能存在一个图片,如果有两个图片,或者多个,就没法上传了。比较困惑怎么会有这样的事情呢?

知道今天开发完后我才测试了下,发现同一个页面单个上传N个图都是没有问题的。

下面是实例。

http://files.cnblogs.com/bin-pureLife/ajaxupload.zip

发现我上面遇到的问题是不存在,另外看了下实现原理,是通过构造了一个不可见的iframe,然后在发送http请求达成的。

我项目中遇到这种问题的原因。

排查:

这是调用upload前的方法。

function doUpload(o){        $(o).attr(name,userphoto)        $(o).attr(id,userphoto)        o = (o.attributes[bin].nodeValue)        if(o == a){           //填充一个假地址           $("#showpage_sty_1").val(ed);           upload(/StoreManage/upload/key/showimage/tempname/userphoto,show_1,userphoto);        }else if(o =="b"){            $("#showpage_sty_2").val(ed);            upload(/StoreManage/upload/key/ewmimage/tempname/userphoto,show_2,userphoto);        }else if(o == c){            $("#showpage_sty_3").val(ed);            upload(/StoreManage/upload/key/showimage/tempname/userphoto,show_3,userphoto);        }    }

动态的先加上去 属性name  和 ID 

我之前用的是类似

id=userphoto1 name = userphoto1

id=userphoto2 name = userphoto2

id=userphoto3 name = userphoto3

就和今天例子中写的一样,但是我发现请求一过去,只有第一个能够打印不为空的$_FILE 。

确定请求路径正确;

 

function upload(url,replaceUrl,fileElementId){    $.ajaxFileUpload    (        {            url:url, //用于文件上传的服务器端请求地址            secureuri: false, //一般设置为false            fileElementId: fileElementId, //文件上传空间的id属性  <input type="file" id="file" name="file" />            dataType: HTML, //返回值类型 一般设置为json            success: function (data, status)  //服务器成功响应处理函数            {                if(data != "error"){                    $("#"+replaceUrl).attr(src,data);                }                //无需理解这段代码。为了上传。                if(replaceUrl == show_1){                    $(":file").eq(0).removeAttr(name)                    $(":file").eq(0).removeAttr(id)                }else if(replaceUrl == show_2){                    $(":file").eq(1).removeAttr(name)                    $(":file").eq(1).removeAttr(id)                }else{                    $(":file").eq(2).removeAttr(name)                    $(":file").eq(2).removeAttr(id)                }            },            error: function (data, status, e)//服务器响应失败处理函数            {                alert(e);            }        }    )}

这是我出现问题后改成这样子了,就解决了问题。

 

源码解读:

jQuery.extend({      //在方法内创建添加一个iframe  
  
//style="position:absolute; top:-9999px; left:-9999px" 让其在界面上看不见 createUploadIframe: function(id, uri) {
//create frame var frameId = jUploadFrame + id; var iframeHtml = <iframe id=" + frameId + " name=" + frameId + " style="position:absolute; top:-9999px; left:-9999px"; if(window.ActiveXObject) { if(typeof uri== boolean){ iframeHtml += src="http://www.mamicode.com/ + javascript:false + "; } else if(typeof uri== string){ iframeHtml += src="http://www.mamicode.com/ + uri + "; } } iframeHtml += />; jQuery(iframeHtml).appendTo(document.body); return jQuery(# + frameId).get(0); }, createUploadForm: function(id, fileElementId, data) { //create form 创建表单, var formId = jUploadForm + id; var fileId = jUploadFile + id; var form = jQuery(<form action="" method="POST" name=" + formId + " id=" + formId + " enctype="multipart/form-data"></form>); if(data) { for(var i in data) { jQuery(<input type="hidden" name=" + i + " value="http://www.mamicode.com/ + data[i] + " />).appendTo(form); } } var oldElement = jQuery(# + fileElementId);//取到之前的 也就是我们传过来的 file的id var newElement = jQuery(oldElement).clone();//把代码克隆过来 jQuery(oldElement).attr(id, fileId);//修改了原来的file的ID 属性 jQuery(oldElement).before(newElement);//在旧的file前面加上新的file对象 jQuery(oldElement).appendTo(form);//把原来的对象传入到创建的表单中去      //问题应该就在这里 在这里完成 file的克隆, 只有一种可能,那就是当第一个图片传递完成之后,当第二次点击传第二张图片的时候,依旧这里取得还是第一个的file 所以才会为空。
     问题应该出在,file id 没有动态对应好。
//set attributes jQuery(form).css(position, absolute); jQuery(form).css(top, -1200px); jQuery(form).css(left, -1200px); jQuery(form).appendTo(body); return form; }, ajaxFileUpload: function(s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = new Date().getTime() var form = jQuery.createUploadForm(id, s.fileElementId, (typeof(s.data)==undefined?false:s.data)); var io = jQuery.createUploadIframe(id, s.secureuri);
      //分别穿件 form 和 iframe
var frameId = jUploadFrame + id; var formId = jUploadForm + id;
      
// Watch for a new set of requests if ( s.global && ! jQuery.active++ ) { jQuery.event.trigger( "ajaxStart" ); //触发ajaxStart方法 } var requestDone = false; // Create the request object var xml = {} if ( s.global ) jQuery.event.trigger("ajaxSend", [xml, s]);//触发ajaxSend方法 // Wait for a response to come back

      //回调函数 var uploadCallback = function(isTimeout) { var io = document.getElementById(frameId);//获取iframe 对象 try { if(io.contentWindow) { 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; }else if(io.contentDocument) { 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") { requestDone = true; var status;
          //请求状态 成功 或者 不成功,
try { status = isTimeout != "timeout" ? "success" : "error"; // Make sure that the request was successful or notmodified if ( status != "error" ) { // process the data (runs the xml through httpData regardless of callback) var data =http://www.mamicode.com/ jQuery.uploadHttpData( xml, s.dataType ); // If a local callback was specified, fire it and pass it the data if ( s.success ) s.success( data, status ); // Fire the global callback if( s.global ) jQuery.event.trigger( "ajaxSuccess", [xml, s] ); } else jQuery.handleError(s, xml, status); } catch(e) { status = "error"; jQuery.handleError(s, xml, status, e); } // The request was completed if( s.global ) jQuery.event.trigger( "ajaxComplete", [xml, s] ); // Handle the global AJAX counter if ( s.global && ! --jQuery.active ) jQuery.event.trigger( "ajaxStop" ); // Process result if ( s.complete ) s.complete(xml, status); jQuery(io).unbind() setTimeout(function() { try { jQuery(io).remove();//去除穿件的iframe 实际上应该是去除remove就够了. jQuery(form).remove(); //去除创建的 from 表单 } catch(e) { jQuery.handleError(s, xml, null, e); } }, 100) xml = null } } // Timeout checker if ( s.timeout > 0 ) { setTimeout(function(){ // Check to see if the request is still happening if( !requestDone ) uploadCallback( "timeout" ); }, s.timeout); } try { var form = jQuery(# + formId); jQuery(form).attr(action, s.url); jQuery(form).attr(method, POST); jQuery(form).attr(target, frameId); if(form.encoding) { jQuery(form).attr(encoding, multipart/form-data); } else { jQuery(form).attr(enctype, multipart/form-data); } jQuery(form).submit(); } catch(e) { jQuery.handleError(s, xml, null, e); } jQuery(# + frameId).load(uploadCallback ); return {abort: function () {}}; }, uploadHttpData: function( r, type ) { var data = http://www.mamicode.com/!type; data = type == "xml" || data ? r.responseXML : r.responseText; // If the type is "script", eval it in global context if ( type == "script" ) jQuery.globalEval( data ); // Get the JavaScript object, if JSON is used. if ( type == "json" ) eval( "data = http://www.mamicode.com/" + data ); // evaluate scripts within html if ( type == "html" ) jQuery("<div>").html(data).evalScripts(); return data; }})

 

ajax图片单个上传(ajaxfileupload.js)