[方案]JS模拟表单方式下载文件
近期在调整代码的时候,遇到了一个小问题:
在程序里面需要下载文件,最开始的采取的做法是window.open和window.location.href这两种形式请求后台下载文件的,贴上代码:
前台关键代码:
function downloadFile(url){ if($.browser.msie) { // IE下打开空下载页面 window.open(glo.path + url , "_blank" , "width=500,height=400") ; }else{ window.location.href = url.replace(/\|/g, "&"); } }
后台关键代码:
@RequestMapping("/downloadFile") public void download(HttpServletRequest request, HttpServletResponse response) { logger.info("ajax download file"); response.setCharacterEncoding("utf-8"); response.setContentType("multipart/form-data");//application/octet-stream InputStream inputStream = null; OutputStream os = null; try { String path = PropertiesUtil.getValue("filedisk");//filedisk D:\upload_file\demo\ String downFile = "2018\02\10\test.pdf"; String fileNameStr = downFile.substring(downFile.lastIndexOf("\\"), downFile.lastIndexOf(".")); fileNameStr = fileNameStr.replaceAll(" ", ""); String exp = downFile.substring(downFile.lastIndexOf("."),downFile.length()); String fileName = fileNameStr.substring(1, fileNameStr.length())+exp; response.setHeader("Content-Disposition", "attachment;fileName="+ java.net.URLEncoder.encode(fileName, "UTF-8")); File file = new File(path+ downFile); if (file != null && file.exists()) { inputStream = new FileInputStream(new File(path+ downFile)); os = response.getOutputStream(); byte[] b = new byte[2048]; int length; while ((length = inputStream.read(b)) > 0) { os.write(b, 0, length); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { // 这里主要关闭。 try { if(null != os){ os.close(); } } catch (IOException e) { } try { if(null != inputStream){ inputStream.close(); } } catch (IOException e) { } } }
上面这代码的最大问题就是,当下载文件不存在时就会出现页面加载失败的情况。采用window.open这种方式就会打开一个新的窗口页面出现请求失败;采用window.location.href这种形式就会在当前页面直接跳转,然后显示页面加载失败的情况。
然后着手修改,模拟表单提交后台的形式,前端代码修改如下:
function downloadFile(url){ var form = $("<form></form>").attr("action", url).attr("method", "post"); // 隐藏域传递参数 form.append($("<input></input>").attr("type", "hidden").attr("name", "downFileName").attr("value", 'Demo.txt')); form.appendTo('body').submit().remove(); }
上面就是将前台的下载方法通过模拟表单提交的方式实现post传递数据。OK,到这里,开头的那个问题,解决,收工。