1. 程式人生 > >ajaxFileUpload.js 無重新整理上傳圖片,支援多個引數同時上傳,支援 ie6-ie10

ajaxFileUpload.js 無重新整理上傳圖片,支援多個引數同時上傳,支援 ie6-ie10

ajaxFileUpload 無重新整理上傳的原理:

在頁面動態建立 form 表單和 ifram 貞,設定 form 表單提交的目標為 ifram 貞,
將檔案域和要 post 的引數動態寫入 form 表單中,然後提交 from 表單。
通過 window.attachEvent 向 ifram 貞的 onload 事件中註冊監聽事件響應回撥函式。

1.html 部分

<input name="imgfile1" id="imgfile1" style="width: 200px; height: 25px;" size="38" type="file" />
<div id="imgContainer1"></div>

2.呼叫部分
  function uploadImg(imgfileId, imgcontainerId) {
    $.ajaxFileUpload({
      fileElementId: imgfileId,
      url: '/UploadImage',
      dataType: 'json',
      data: { id: 'aaa', name: 'bbb' },
      beforeSend: function (XMLHttpRequest) {
        //("loading");
      },
      success: function (data, textStatus) {
        var img = "<img src='' width='300' height='300' />";
        $("#" + imgcontainerId).append(img);
      },
      error: function (XMLHttpRequest, textStatus, errorThrown) {
        var img = "圖片上傳失敗!";
        $("#" + imgcontainerId).append(img);
        var msg = "伺服器出錯,錯誤內容:" + XMLHttpRequest.responseText;
        $.messager.showWin({ msg: msg, title: '錯誤提示', color: 'red' });
      },
      complete: function (XMLHttpRequest, textStatus) {
        //("loaded");
      }
    });
  }

3.ajaxFileUpload.js 全部程式碼
/*
  131108-xxj-ajaxFileUpload.js 無重新整理上傳圖片 jquery 外掛,支援 ie6-ie10 
  依賴:jquery-1.6.1.min.js
  主方法:ajaxFileUpload 接受 json 物件引數
  引數說明:
  fileElementId:必選,上傳檔案域ID
  url:必選,傳送請求的URL字串
  fileFilter:可選,限定上傳檔案的格式(.jpg,.bmp,.gif,.png)
  fileSize:可選,0 為無限制(IE瀏覽器不相容)
  data:可選,將和檔案域一同post的引數(json物件)
  其它:$.ajax 的引數均為可選引數
  注:如遇到‘無法訪問’的指令碼錯誤提示則需要在響應流中加一段腳塊一同輸出:<script ...>document.domain = 'xxx.com';</script>
*/
jQuery.extend({
  //建立 iframe 元素,接受提交及響應
  createUploadIframe: function(id, uri) {
    //create frame
    var frameId = 'jUploadFrame' + id;


    if (window.ActiveXObject) {
      //fix ie9 and ie 10-------------
      if (jQuery.browser.version == "9.0" || jQuery.browser.version == "10.0") {
        var io = document.createElement('iframe');
        io.id = frameId;
        io.name = frameId;
      } else if (jQuery.browser.version == "6.0" || jQuery.browser.version == "7.0" || jQuery.browser.version == "8.0") {
        var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
        if (typeof uri == 'boolean') {
          io.src = 'javascript:false';
        } else if (typeof uri == 'string') {
          io.src = uri;
        }
      }
    } else {
      var io = document.createElement('iframe');
      io.id = frameId;
      io.name = frameId;
    }
    io.style.position = 'absolute';
    io.style.top = '-1000px';
    io.style.left = '-1000px';


    document.body.appendChild(io);


    return io;
  },
  //建立 from 元素,用於提交的表單
  createUploadForm: function(id, fileElementId, postData) {
    //create form
    var formId = 'jUploadForm' + id;
    var fileId = 'jUploadFile' + id;
    var form = $('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
    var oldElement = $('#' + fileElementId);
    var newElement = $(oldElement).clone();


    $(oldElement).attr('id', fileId);
    $(oldElement).before(newElement);
    $(oldElement).appendTo(form);
    //新增自定義引數
    if (postData) {
      //遞迴遍歷JSON所有鍵值


      function recurJson(json) {
        for (var i in json) {
          //alert(i+"="+json[i])
          $("<input name='" + i + "' id='" + i + "' value='" + json[i] + "' />").appendTo(form);
          if (typeof json[i] == "object") {
            recurJson(json[i]);
          }
        }
      }


      recurJson(postData);
    }
    //set attributes
    $(form).css('position', 'absolute');
    $(form).css('top', '-1200px');
    $(form).css('left', '-1200px');
    $(form).appendTo('body');
    return form;
  },
  //上傳檔案
  //s 引數:json物件
  ajaxFileUpload: function(s) {
    s = jQuery.extend({fileFilter:"",fileSize:0}, jQuery.ajaxSettings, s);
    //檔案篩選
    var fielName = $('#' + s.fileElementId).val();
    var extention = fielName.substring(fielName.lastIndexOf(".") + 1).toLowerCase();
    if (s.fileFilter && s.fileFilter.indexOf(extention) < 0) {
      alert("僅支援 (" + s.fileFilter + ") 為字尾名的檔案!");
      return;
    }
    //檔案大小限制
    if (s.fileSize > 0) {
      var fs = 0;
      try {
        if (window.ActiveXObject) {
          //IE瀏覽器
          var image = new Image();
          image.dynsrc = fielName;
          fs = image.fileSize;
        } else {
          fs = $('#' + s.fileElementId)[0].files[0].size;
        }
      } catch(e) {
      }
      if (fs > s.fileSize) {
        alert("當前檔案大小 (" + fs + ") 超過允許的限制值 (" + s.fileSize +")!");
        return;
      }
    }
    var id = new Date().getTime();
    //建立 form 表單元素
    var form = jQuery.createUploadForm(id, s.fileElementId, s.data);
    //建立 iframe 貞元素
    var io = jQuery.createUploadIframe(id, s.secureuri);
    var frameId = 'jUploadFrame' + id;
    var formId = 'jUploadForm' + id;
    //監測是否有新的請求
    if (s.global && !jQuery.active++) {
      jQuery.event.trigger("ajaxStart"); //觸發 AJAX 請求開始時執行函式。Ajax 事件。
    }
    var requestDone = false;
    //建立請求物件
    var xml = {};
    if (s.global)
      jQuery.event.trigger("ajaxSend", [xml, s]); //觸發 AJAX 請求傳送前事件
    //上載完成的回撥函式
    var uploadCallback = function(isTimeout) {
      var io = document.getElementById(frameId);
      try {
        //存在跨域指令碼訪問問題,如遇到‘無法訪問’提示則需要在響應流中加一段腳塊:<script ...>document.domain = 'xxx.com';</script>
        if (io.contentWindow) { //相容各個瀏覽器,可取得子視窗的 window 物件
          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) { //contentDocument Firefox 支援,> ie8 的ie支援。可取得子視窗的 document 物件。
          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.handleErrorExt(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") {
            //處理資料(執行XML通過httpData不管回撥)
            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.handleErrorExt(s, xml, status);
        } catch(e) {
          status = "error";
          jQuery.handleErrorExt(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 {
            $(io).remove();
            $(form).remove();
          } catch(e) {
            jQuery.handleErrorExt(s, xml, null, e);
          }


        }, 100);


        xml = null;


      }
    };
    //超時檢查,s.timeout 毫秒後呼叫 uploadCallback 回撥函式提示請求超時
    if (s.timeout > 0) {
      setTimeout(function() {
        // Check to see if the request is still happening
        if (!requestDone) uploadCallback("timeout");
      }, s.timeout);
    }
    try {
      //設定動態 form 表單的提交引數
      // var io = $('#' + frameId);
      var form = $('#' + formId);
      $(form).attr('action', s.url);
      $(form).attr('method', 'POST');
      $(form).attr('target', frameId);
      if (form.encoding) {
        form.encoding = 'multipart/form-data';
      } else {
        form.enctype = 'multipart/form-data';
      }
      $(form).submit();


    } catch(e) {
      jQuery.handleErrorExt(s, xml, null, e);
    }
    //向動態表單的頁面載入事件中註冊回撥函式
    if (window.attachEvent) {
      document.getElementById(frameId).attachEvent('onload', uploadCallback);
    } else {
      document.getElementById(frameId).addEventListener('load', uploadCallback, false);
    }
    return {
      abort: function() {
      }
    };


  },
  //上傳檔案
  uploadHttpData: function(r, type) {
    //alert("type=" + type + ";uploadHttpData" + JSON.stringify(r))
    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();
    //alert($('param', data).each(function(){alert($(this).attr('value'));}));
    return data;
  },
  handleErrorExt: function(s, xhr, status, e) {
    // If a local callback was specified, fire it
    if (s.error) {
      s.error.call(s.context || s, xhr, status, e);
    }


    // Fire the global callback
    if (s.global) {
      (s.context ? jQuery(s.context) : jQuery.event).trigger("ajaxError", [xhr, s, e]);
    }
  }
});