最近在折騰僞ajax異步上傳文件。jquery
網上搜索了一下,發現大部分方法的input file控件都侷限於form中,若是是在form外的呢?ajax
必須動態生成一個臨時form和臨時iframe,action指向上傳文件URL,target指向臨時iframe,同時在form中生成一個file控件;安全
可是出於安全的考慮,file控件都是隻讀的,不能動態設置其value值,因此在臨時form中生成的file控件是永遠沒法綁定相應文件的,除非用戶手動操做;app
這時,我想到了jquery的clone方法,因而我便寫了以下代碼:異步
var $cloneFile = $file.clone(true); $cloneFile.removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM"));
一測試,發現後臺接收到的文件永遠是空的,才知道jquery的clone方法對於file控件也是無能爲力,想一想也以爲有道理,仍是基於安全的考慮。ide
通過一番思考,我想到了如下方法,仍是基於jquery的clone,不過做了些調整:函數
//克隆file控件 var $cloneFile = $file.clone(true); //將原來的file控件移動到臨時form中 //以克隆的file控件代替原來的file控件 $file.hide().after($cloneFile).removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM"));
我將最原始的file控件移到了臨時form中,而將克隆的代替了其原來位置。post
測試,OK,搞定!如下是全部JS代碼,基於sea.js的測試
/** * @author weeksun23 * @date 2013-08-07 23:20 * @description 文件異步上傳幫助類,它能幫助你將頁面上任意一個file控件的文件異步上傳到指定URL中 * @param $file file控件的jquery對象 * @param uploadUrl 上傳URL * @param type 上傳文件的後綴限制 (jpg|gif|bmp|jpeg) * @param callback 各類回調函數 * @dependency jquery * @extra 佔用了以下3個HTML ID:FILE_UPLOAD_TEMPDV FILE_UPLOAD_TEMPFORM FILE_UPLOAD_TEMPFRAME */ define(function(require, exports, module) { function FileUpload($file,uploadUrl,type,callback){ this.$file = $file; this.uploadUrl = uploadUrl; this.type = type || null; this.callback = $.extend({ complete : function(response) {}, //上傳文件後回調 beforeUpload : function(fileName) {}, //上傳前回調,返回false可停止上傳 afterUpload : function() {} //觸發上傳後回調 },callback); } FileUpload.prototype.upload = function(){ var $file = this.$file, filePath = $file.val(), type = this.type, fileFullName = filePath.substring(filePath.lastIndexOf("\\") + 1); if(!filePath) return false; if(type !== null){ var ext = fileFullName.substring(fileFullName.lastIndexOf(".") + 1); if(type.indexOf(ext) === -1) return false; } var callback = this.callback; if(callback.beforeUpload.call(this,fileFullName) === false) return false; $("body").append(["<div id='FILE_UPLOAD_TEMPDV' style='display:none;'>", "<form id='FILE_UPLOAD_TEMPFORM' enctype='multipart/form-data' method='post' action='", this.uploadUrl,"' target='FILE_UPLOAD_TEMPFRAME'>", "</form>", "<iframe id='FILE_UPLOAD_TEMPFRAME' name='FILE_UPLOAD_TEMPFRAME'></iframe>", "</div>"].join("")); $("#FILE_UPLOAD_TEMPFRAME").on("load",function(){ var response = this.contentWindow.document.body.innerHTML; callback.complete(response); $(this).off("load"); $("#FILE_UPLOAD_TEMPDV").remove(); }); //克隆file控件 var $cloneFile = $file.clone(true); //將原來的file控件移動到臨時form中 //以克隆的file控件代替原來的file控件 $file.hide().after($cloneFile).removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM")); this.$file = $cloneFile; $("#FILE_UPLOAD_TEMPFORM").submit(); callback.afterUpload.call(this); //經過驗證 開始上傳 return true; }; module.exports = FileUpload; });