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="' + '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; } })
积累知识,分享知识,学习知识。
原文地址:https://www.cnblogs.com/bin-pureLife/p/4063655.html