FILE 控件文件异步上传问题汇总

1. FILE 控件的美化

错误示例】file控件的美化,我们想到的方法是将FILE控件本身隐藏,然后使用div+css模拟一个FILE控件,当用户单击这个模拟的FILE控件时,再触发隐藏的真实的FILE控件的单击事件,进而打开本地文件选择框。这种方式会遇到一个浏览器安全问题,并且JavaScript会提示拒绝访问的错误。

    <!--- html 代码片段 --->
    <div id="fake_file_ctrl">
        <img src="beatiful_upload_btn.png"/>
    </div>  
    <input type="file" class="hidden_ctrl" id="file_upload" name="file_upload"/>
    //javascript 代码片段
    $("#fake_file_ctrl").click(function(){
        $("#file_upload").trigger("click");
        //此句出错,在IE浏览器下会提示拒绝访问。
    });

正确示例】上面错误示例中的思路是正确的,但是如何避免拒绝访问的错误呢?既然JavaScript找不到出路,那只好寻求CSS了.原理如下: 将实际的FILE控件透明地覆盖在模拟控件上,这样当用户单击模拟控件的时候,同时也单击了实际的FILE控件。

#fake_file_ctrl{
    position:relative;
    left:0px;
    top:0px; 
    width:400px;
    height:200px;
}
#file_upload{
    position:relative;
    left:0px;
    top:-200px; /* 将实际的FILE控件和模拟FILE控件重叠*/
    width:400px;
    height:200px;
    opacity:0; /* 完全透明 支持opacity的浏览器*/
    filter:alpha(opacity=0); /* IE浏览器 */
    -moz-opacity:0;      /* 老版Mozilla */
    -khtml-opacity:0;  /* 老版Safari */           
}
2. ajaxUploadFile.js文件异步提交的问题

我们知道,在HTML中直接单击input控件上传图片文件的时候会跳转到文件上传处理页面,导致本页面刷新,用户体验非常糟糕。利用ajaxUploadFile.js这样的jQuery异步上传插件可以避免上述情况。这个插件本身也有很多局限(不能选择多个文件同时上传,不能在上传文件的同时提交附加参数),好在第二个局限可以通过修改ajaxUploadFile.js源代码进行弥补。实际使用过程中可能还会遇到其他的问题,具体如下:

2.1 运行时报错:jQuery.handleError is not a function

这个错误是由于ajaxfileupload.js 是在jquery1.4.2版本之前写的,Jquery之后的版本已经没有了handleError 方法,所以可以将1.4.2版本中的该方法复制到该js中。

//handleError 方法在jquery1.4.2之后移除了,此处重写改方法
//注意这个方法在ajaxUploadFile.js添加的正确位置。在所有handleError方法调用之前。
handleError: 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] );
    }
},
2.2 无法提交附加参数,只能上传文件

需要修改ajaxUploadFile.js源代码,改动的地方有两个.
第一处是 将原createUploadForm: function(id, fileElementId) 方法添加一个data参数,并将data中的数据拼接进去即可。代码如下:

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>');
    var oldElement = jQuery('#' + fileElementId);
    var newElement = jQuery(oldElement).clone();
    jQuery(oldElement).attr('id', fileId);
    jQuery(oldElement).before(newElement);
    jQuery(oldElement).appendTo(form);

    // 增加参数的支持
    if (data) {
        for (var i in data) {
            $('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
        }
    }

    //set attributes
    jQuery(form).css('position', 'absolute');
    jQuery(form).css('top', '-1200px');
    jQuery(form).css('left', '-1200px');
    jQuery(form).appendTo('body');
    return form;
},  

第二处是 调用createUploadForm方法地方,如下所示:

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);
   var form = jQuery.createUploadForm(id, s.fileElementId, s.data); //新增这一句,替换上面注释的语句

   var io = jQuery.createUploadIframe(id, s.secureuri);
2.3 执行成功后,始终指向error方法,无法执行sucess方法

这个是由于ajaxfileupload.js 处理返回data的时候,没有考虑后台返回的是字符串的情况。需要修改uploadHttpData方法:

if ( type == "json" ){
    // 如果返回的是字符串(JSON格式字符串),下面会报错,导致无法进入sucess方法 加上"引号转化为字符串后就没事了。
    // eval( "data = " + data );//注释掉这一句
    eval('data = " '+data+' " ');
}

<<<先整理到这,后续补充. ^_^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值