最近的项目里,客户要求必须兼容目前主流浏览器和IE8、IE9,其中有个功能需要导入数据,于是开启了多年未曾碰过的IE8上传文件并回调的苦逼之旅:
1、用flash上传?现在主流的浏览器想启用flash,对大部分普通用户来讲,都不是件分分钟能搞定的事,果断放弃。
2、用文本域上传吧。但是上传完文件后,界面上还需要把上传文件中的数据渲染到界面上,于是乎就选择了jquery的ajaxSubmit。上代码:
(1)html部分:
1 <form id="uploadFrm" method="post" enctype="multipart/form-data"> 2 <div class="col-xs-8"> 3 <div class="form-group"> 4 <label for="accessFile4IE" 5 class="col-xs-2 control-label">请选择文件:</label> 6 <div class="col-xs-6"> 7 <input class="form-control" id="accessFile4IE" name="accessFile4IE" type="file" 8 accept=".mdb"> 9 </div> 10 <div class="col-xs-4"> 11 <button onclick="doUpload4IE()" class="btn btn-info btn-sm"><i class="fa fa-upload"></i> 12 上传文件 13 </button> 14 <button onclick="doImport()" class="btn btn-info btn-sm"><i 15 class="fa fa-cloud-download"></i> 接收上报数据 16 </button> 17 </div> 18 </div> 19 </div> 20 </form>
(2)js部分
1 function doUpload4IE(){ 2 if ($('#accessFile4IE').val()==null || $('#accessFile4IE').val().length<4){ 3 return; 4 } 5 6 var fileName=$('#accessFile4IE').val(); 7 if(fileName.substr(fileName.length-4).toLowerCase()!=".mdb"){ 8 $.mfmtAlertError('请上传mdb文件!'); 9 return; 10 } 11 12 $('#uploadFrm').ajaxSubmit({ 13 url: '/sys/uploadIE', 14 type: 'post', 15 dataType: 'text', //数据类型 16 ContentType: 'multipart/form-data', 17 // ContentType必须 18 success: function (res) { 19 var r = JSON.parse(res); 20 if (r.result) { 21 $('#filePath').val(r.data); 22 reloadList(true); 23 } else { 24 $.mfmtAlertError(r.message); 25 } 26 }, 27 error: function () { 28 $.mfmtAlertError('文件上传失败!'); 29 } 30 } 31 ); 32 return false; 33 }
(3)Java部分
1 @RequestMapping(value = "/uploadIE",method = RequestMethod.POST, produces = "text/plain;charset=UTF-8") 2 @ResponseBody 3 public String uploadIE(MultipartHttpServletRequest multRequest) { 4 String uploadDir = PropertyUtil.getProperty("tmpFileDir"); 5 OperationResultVo result=new OperationResultVo(); 6 try { 7 Map<String, MultipartFile> fileMap = multRequest.getFileMap(); 8 for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) { 9 MultipartFile mf = entry.getValue(); // 获得原始文件名 10 String url = FileDUUtil.UploadFile(uploadDir, "", mf); 11 result = OperationResultVo.defaultSuccessResult(url); 12 break; 13 } 14 } catch (IOException e) { 15 result = OperationResultVo.defaultFailureResult(e); 16 } 17 18 return JsonUtil.toJson(result); 19 }
这里的重点是RequestMapping注解里produces =“text/plain;charset=UTF-8”不能少。
3、问题来了:点击”上传文件按钮“后,页面跳转了,ajaxSubmit的回调根本没机会执行。
4、百度吧!很多同学都说在调用了ajaxSubmit函数后,加上return false可以阻止跳转。
在js的doUpload4IE函数里,末尾加上了return false,一点用处都没有!IE8不行,IE10不行,IE9电脑上没有。
5、继续搜索,发现可以把form的target指向一个隐藏的iframe,这样就可以阻止跳转。但是据说这样会带来新的问题:form的数据传不到后端。不管它,先试试再说!
修改html代码:
1 <form id="uploadFrm" method="post" enctype="multipart/form-data" target="hidden-frame"> 2 <div class="col-xs-8"> 3 <div class="form-group"> 4 <label for="accessFile4IE" 5 class="col-xs-2 control-label">请选择文件:</label> 6 <div class="col-xs-6"> 7 <input class="form-control" id="accessFile4IE" name="accessFile4IE" type="file" 8 accept=".mdb"> 9 </div> 10 <div class="col-xs-4"> 11 <button onclick="doUpload4IE()" class="btn btn-info btn-sm"><i class="fa fa-upload"></i> 12 上传文件 13 </button> 14 <button onclick="doImport()" class="btn btn-info btn-sm"><i 15 class="fa fa-cloud-download"></i> 接收上报数据 16 </button> 17 </div> 18 </div> 19 </div> 20 </form> 21 <iframe name="hidden-frame" class="hidden-frame" style="display: none" id="hiddenFrame"></iframe>
修改之后,可以了!既没有跳转,同时也把文件post到了服务端,ajaxSubmit的回调函数也成功执行了。