伪ajax上传文件
最近在折腾伪ajax异步上传文件。
网上搜索了一下,发现大部分方法的input file控件都局限于form中,如果是在form外的呢?
必须动态生成一个临时form和临时iframe,action指向上传文件URL,target指向临时iframe,同时在form中生成一个file控件;
但是出于安全的考虑,file控件都是只读的,不能动态设置其value值,所以在临时form中生成的file控件是永远无法绑定相应文件的,除非用户手动操作;
这时,我想到了jquery的clone方法,于是我便写了如下代码:
var $cloneFile = $file.clone(true); $cloneFile.removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM"));
一测试,发现后台接收到的文件永远是空的,才知道jquery的clone方法对于file控件也是无能为力,想想也觉得有道理,还是基于安全的考虑。
经过一番思考,我想到了以下方法,还是基于jquery的clone,不过作了些调整:
//克隆file控件 var $cloneFile = $file.clone(true); //将原来的file控件移动到临时form中 //以克隆的file控件代替原来的file控件 $file.hide().after($cloneFile).removeAttr("id").appendTo($("#FILE_UPLOAD_TEMPFORM"));
我将最原始的file控件移到了临时form中,而将克隆的代替了其原来位置。
测试,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; });
分类: javascript