标签:style blog http io color os ar java for
开发过程中发现,页面总是只能存在一个图片,如果有两个图片,或者多个,就没法上传了。比较困惑怎么会有这样的事情呢?
知道今天开发完后我才测试了下,发现同一个页面单个上传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="‘ + ‘javascript:false‘ + ‘"‘; } else if(typeof uri== ‘string‘){ iframeHtml += ‘ src="‘ + 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="‘ + 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 = 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 = !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 = " + data ); // evaluate scripts within html if ( type == "html" ) jQuery("<div>").html(data).evalScripts(); return data; } })
标签:style blog http io color os ar java for
原文地址:http://www.cnblogs.com/bin-pureLife/p/4063655.html