类似ajax文件上传功能 其一(只针对同一个页面只有一个上传功能)
写了一个简单的类似ajax上传文件的功能,原理当然不是真正的通过ajax方式上传,而是利用iframe来做的这是其中的一种写法:
先来分析一下原理,利用js来创建一个iframe,这个iframe的src指向一个静态页面。这个静态页面当中有一个Form表单
进行提交。后台提交成功后让其运行一个父窗口的js函数,并返回上传成功的文件路径、
先来看js,由于有一些参数是可变的,所以代码上有些混杂.(程序当中为方便,用到了jquery框架)
var Upload = {};Upload = { formId:"D_upload_form", imgURL : "http://www.xxxx.com:8080/img", action : "/img/upload.htm", currentFilePath:null, allFilePath:new Array(), imgPreDiv:null, uploadInfo:null, checkType:2,//默认检测类型为图片格式 imgTemplate:null, //图片显示模板格式 maxNum:5, //最大上传数量 hasUploadNum:0,//已经上传的数量 /** * 如果需要修改默认参数调用此方法. */ setting:function(uploadURL, upladAction, checkType) { Upload.imgURL = uploadURL || Upload.imgURL; Upload.action = upladAction || Upload.action; Upload.checkType = checkType || Upload.checkType; }, /** * 创建文件上传 * @param fileID 当前file控件ID * @param imgListDivId 如果是图片,则可设置图片上传完成后显示的缩略图的位置 * @param infoId 提示用户正在上传的信息所在的标签ID * @param imgTemplate 图片上传后显示的的格式模板,程序根据此模板自动生成后续的图片样式 */ createUpload:function(fileID, imgListDivId, infoId, imgTemplate) { if (typeof($) != "function") { alert("请导入jquery1.2.6以上版本JS文件"); return; } var fileInput = $("#" + fileID); var iframeWidth = fileInput.parent().css("width") || "250"; var iframeHeight = fileInput.parent().css("height") || "30"; var html = "<iframe frameborder='0' id='D_upload_iframe' scrolling='no' src='" + Upload.imgURL + "/html/upload.html' width='" + iframeWidth + "' height='" + iframeHeight + "'></iframe>"; fileInput.parent().html(html); if (imgListDivId != null || imgListDivId != "") { Upload.imgPreDiv = $("#" + imgListDivId); } if (infoId != null || infoId != "") { Upload.uploadInfo = $("#" + infoId); } if (imgTemplate != null || imgTemplate != "") { Upload.imgTemplate = $("#" + imgTemplate).html(); } }, /** * 供后台程序调用,设置当前上传成功的文件路径 * @param path 上传后的路径 */ setFilePath:function(path) { Upload.currentFilePath = path; Upload.allFilePath.push(path); //var img = "<img src='" + path + "' alt='上传的图片,可删除'/>"; var img = Upload.imgTemplate.replace("src=\"\"", "src=\"" + path + "\""); if (Upload.imgPreDiv != null) { Upload.imgPreDiv.append(img); } history.back(); Upload.uploadInfo.hide(); }, /** * 供后台程序调用,当上传出现错误时弹出错误提示框 * @param error 错误信息 */ uploadError:function(error) { alert(error); history.back(); Upload.uploadInfo.hide(); }, /** * 获取当前上传的文件路径 */ getFilePath:function() { return Upload.currentFilePath; }, /** * 显示正在上传信息 */ showUploadInfo:function() { Upload.uploadInfo.show(); }};上面的JS 方法基本没什么可说的,通过获取当前页面当中的一个input对象,将其替换成一个iframe并保留一些参数
下面来看iframe静态页面内容:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head> <title></title> <meta http-equiv="Content-type" content="text/html;chartset=utf-8"/></head><body style="padding:0;"><form style="padding:0;" method="post" action="" enctype="multipart/form-data"> <input type="file" name="fileName" onchange="listernInputChange(this,this.form);"/></form></body><script type="text/javascript"> function iframeLoad() { if (parent.Upload == null || parent.Upload == "undefined") { alert("您的设置可能问题,或访问了不该的页面!"); history.back(); } else { document.forms.action = parent.Upload.imgURL + parent.Upload.action; } } function listernInputChange(input, form) { var form1 = form || document.forms; var pattern = /\.(jpg|jpeg|gif|bmp|png)(\s|$)/i; if (parent.Upload.checkType == 1) { pattern = /\.(css)(\s|$)/i; } else if (parent.Upload.checkType == 3) { pattern = /\.(swf)(\s|$)/i; } var url = input.value; if (parent.Upload.hasUploadNum < parent.Upload.maxNum) { if (!pattern.test(url)) { alert("上传的文件格式不正确"); } else { parent.Upload.showUploadInfo(); form1.submit(); } parent.Upload.hasUploadNum++; } else { alert("已达到最大上传数量,不可以再上传"); } } iframeLoad();</script></html>iframe页面当中,做了如下事:
1:获取父窗口当中传入的action路径
2:获取用户设置的最大上传数量及上传的文件类型
3:监听浏览按钮的change事件进行表单提交
整个页面调用了父窗口当中的JS函数来获取相关的参数
现在来看后台代码:
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { String imgPath = ""; String sectionPath = ""; String fileName = ""; StringBuffer uploadError = null; try { response.setContentType("text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); //获取当前项目所在的绝对路径 if (DStringUtil.isEmpty(UploadCtrl.CONTEXT_PATH)) { UploadCtrl.CONTEXT_PATH = request.getSession().getServletContext().getRealPath("/"); } //文件保存路径 String path = request.getParameter("savePath"); //检测类型 String checkType = request.getParameter("checkType"); //默认检测的文件类型为图片格式,可以设置指定类型 byte cType = UploadUtil.IMG_TYPE; if (DStringUtil.isEmpty(path)) { path = ConfigUtil.DEFAULT_IMG_PATH; } if ((!DStringUtil.isEmpty(checkType)) && DStringUtil.isNumber(checkType)) { cType = Byte.valueOf(checkType); } sectionPath = UploadCtrl.CONTEXT_PATH + path; uploadError = new StringBuffer(); //保存上传当中的错误信息,有错误时,不回滚 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; MultipartFile file = multipartRequest.getFile("fileName"); if (file.getSize() > 0) { String error = UploadUtil.checkFileExt_SIZE(file, cType, ConfigUtil.MAX_IMG_50K); if (DStringUtil.isEmpty(error)) { imgPath = UploadUtil.uploadTempFile(sectionPath, file, CreateCode.getCode()); fileName = imgPath; imgPath = imgURL + path + "/" + imgPath; } uploadError.append(error); } if (uploadError.length() == 0) { //插入图片 out.println("<html>"); out.println("<head>"); out.println("<title>Insert Image</title>"); out.println("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"); out.println("</head>"); out.println("<body>"); out.println("<script type=\"text/javascript\">parent.Upload.setFilePath(\"" + imgPath + "\")</script>"); out.println("</body>"); out.println("</html>"); } else { out.println("<html>"); out.println("<head>"); out.println("<title>error</title>"); out.println("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"); out.println("</head>"); out.println("<body>"); out.println("<script type=\"text/javascript\">parent.Upload.uploadError(\"" + uploadError.toString() + "\");</script>"); out.println("</body>"); out.println("</html>"); } } catch (Exception e) { logger.error("上传图片:" + e); if (!DStringUtil.isEmpty(imgPath)) { UploadUtil.deleteFile(sectionPath + "/" + fileName); } throw e; } finally { if (uploadError != null && !DStringUtil.isEmpty(uploadError.toString())) { UploadUtil.deleteFile(sectionPath + "/" + fileName); } } return null; }
以上代码当中用了一些工具类,在这里并未给出,重点的是看后面上传成功后如果让其将路径返回给父窗口
查看其中的红色代码,这里利用response写入一段代码,并让其运行父窗口当中的方法,通过传参的方式,将文件路径告之父窗口。
来看演示HTML:
<script type="text/javascript"> $(function() { //创建上传文件,及处理上传成功后的操作 Upload.createUpload("imgFile", "imgList", "D_upload_label_info", "ImageTemplate"); //Upload.createUpload("imgFile2", "imgList2", "", ""); }); </script><%--图片显示模板格式--%><div id="ImageTemplate"> <div> <img src="" alt="图片位置"/></div></div><%--图片显示位置--%><div id="imgList" style="height:150px;"></div><div style="height:30px;"> <%--只是一个占位符--%> <input id="imgFile" type="file" name="imgFile"/></div><div> <label id="D_upload_label_info" style="display:none;">正在上传....</label></div><div> <input id="imgFile2" type="file" name="imgFile"/></div><%--图片显示位置--%><div id="imgList2" style="height:150px;"></div>
以上就是整个上传的过程。
不足之处:目前在同一个页面只能有一个上传的文件选择框,不能有多个不同提交路径及不同参数的上传框。
页:
[1]