在不使用ajax插件进行文件时上传时,貌似只能通过form.submit来完成,但是这样就造成了无法及时得到后台返回的结果,虽然可以通过其他机制(如将上传结果通过request输出到页面上的一个隐藏域中等)。如何在只使用form的submit事件以及input[type=file]来完成文件的上传功能,又能在页面刷新前知道后台的处理结果呢?
可以使用iframe来完成模拟ajax上传文件的功能!
<form id="importForm_Talking" action="importProvinceTalk/${provinceID}?callbackurl=%2fcommon%2fupload_response" method="post" enctype="multipart/form-data"target="check_file_frame">
<input type="file" name="myFiles_Talking" id="myFiles_Talking" size=1 style="cursor:pointer;opacity:0;filter:alpha(opacity=0);width:1px;position:absolute;left:0;top:0;z-index:9999;" />
</form>
<iframe id="check_file_frame" name="check_file_frame" style="display:none;"></iframe>
可以看到:
1、为了避免form.submit提交后页面刷新,所以将 form的target属性指向了一个隐藏的iframe。
2、form的action的内容里面有个callback参数,这个参数是干嘛用的呢?来看一下java后台的代码:
@RequestMapping(value = "/importProvinceTalk/{id}", method = RequestMethod.POST)
public void importProvinceTalk(@RequestParam("myFiles_Talking") MultipartFile file,
@PathVariable("id") long provinceId,
@RequestParam("callbackurl") String callbackurl,
HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/***省略处理代码***/
//将导入结果通过中间页面传回导入资源的页面
String newUrl = callbackurl + "?success=" + result.get("success");
if(result.get("errmsg") != null){
newUrl += "&errmsg=" + URLEncoder.encode(result.get("errmsg").toString(),"utf-8");
}
//response.sendRedirect(newUrl);
RequestDispatcher rDispatcher = request.getRequestDispatcher(newUrl);
rDispatcher.forward(request, response);
}
可以看到,处理结果被传递到了那个callback指向的页面,后台在处理完成后,会将处理结果传送到callback指向的页面。下面来看看callback指向的页面里面有什么内容。
<input type="text" id="success" name="success" value=<%=request.getParameter("success") %> />
<input type="text" id="errmsg" name="errmsg" value=<%=request.getParameter("errmsg") %> />
<script type="text/javascript">
var success = document.getElementById("success").value;
var errmsg = document.getElementById("errmsg").value;
window.parent.uploadCallBack(success, errmsg);
</script>
java后台将处理结果输出到这个页面上来了,那这个callback页面到底以什么样的形式展现呢?
没错,这个callback页面就是展示在上面那个隐藏域iframe里面的,所以它能够调用父页面的uploadCallBack方法,来向用户展示处理的结果。
/** * 导入回调函数 */ function uploadCallBack(success, errmsg) { if (success == "true") { alert("导入成功!"); location.reload(); } else { alert(errmsg); //隐藏导入等待框 $("#wait").modal("hide"); //清楚input-file的value $("input[type='file']").val(""); } }
虽然这个过程有点复杂,但是相对于刷新后再给用户提示上传导入的结果,个人感觉用户体验好多了
很直接的,就是上传文件,然后就知道了操作的结果,然后刷新页面。
欢迎大家给出意见!