浏览 2950 次
锁定老帖子 主题:(原)download后回调刷新页面思路
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|||||||||
---|---|---|---|---|---|---|---|---|---|
作者 | 正文 | ||||||||
发表时间:2010-03-06
最后修改:2010-03-06
这个时候,问题就来了。 看以下代码 response.reset();//可以加也可以不加 response.setContentType("application/x-download");//设置为下载application/x-download String fileNameDisplay = "***.文件名"; fileNameDisplay = URLEncoder.encode(fileNameDisplay,"UTF-8"); response.addHeader("Content-Disposition","attachment;filename=" + fileNameDisplay); String fileNameDownload = this.getClass().getClassLoader().getResource("/").getPath() + fileNameDisplay; OutputStream output = null; FileInputStream fis = null; try { output = response.getOutputStream(); fis = new FileInputStream(fileNameDownload); byte[] b = new byte[1024]; int i = 0; while((i = fis.read(b)) > 0) { output.write(b, 0, i); } output.flush(); } catch(Exception e) { System.out.println("Error!"); e.printStackTrace(); } finally { if(fis != null) { fis.close(); fis = null; } if(output != null) { output.close(); output = null; } } 上面的是很典型的download代码 但是在download的过程中,由于强制将文件流写入response,加上调用了out.close();原来的response将不会去刷新页面。 解决方法一:(适用范围IE7+)此方法在IE6下有此属性,但是测试无效 将download Form的target指向一个iframe。(如果是dialog画面,也可以改变base的target)并且加上以下代码 <iframe id="iframe" name="iframe" width="0px" height="0px"></frame> 注意,这里id和name必须都设,这样才能在IE和Firefox下都支持 var iframe = document.getElementById('iframe'); iframe.onreadystatechange = function() { if (iframe.readyState = "interactive") { // 这里写还原页面的代码 } } readyState有4种状态
当执行out.close()的时候,IE7下刚好执行到interactive,但是在IE6下就无效 在其他浏览器下,网上很多人推荐监听iframe的onload句柄。但是一旦out.close,就不触发onload,所以此法无效 方法二(跟浏览器无关) 思路: 企业级应用下载最花时间的是查询和生成文件操作。所以把这些功能和download分开 先在服务器端生成好一个文件。(这段时间页面上显示遮罩DIV) 加上以下代码 // 在session中放入同步令牌 session.setAttribute(DOWNLOAD_TOKEN, 随机数字); 然后不download,直接回来刷新页面 接下来在页面的onload里执行以下代码 <script type="text/javascript"> // 这里的serverFilePath=你服务器上用于download的路径+文件名(需要在web.xml或者(如果是struts,则要在struts-config.xml里配置)) function downloadFile(serverFilePath) { var iframe = document.getElementById('iframe'); if (iframe) { iframe.src = serverFilePath; } else { window.open(serverFilePath); } } </script> <body onload="downloadFile('${serverFilePath}')"> <input type="hidden" value="${DOWNLOAD_TOKEN}"/> </body> 然后在download的那个Servlet里,判断同步令牌里的数字是否一样。 一样则先 session.remove(DOWNLOAD_TOKEN); 然后download 最后删除文件 虽然问题还是有的,但是由于是用看不见的iframe,所以不用担心重复刷新。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||||||||
返回顶楼 | |||||||||
发表时间:2010-03-06
好復雜哦。
提供的是下載功能,直接通過<a href='文件url連接'>方式指向文件的url給用戶進行下載不就好了嗎? 如果是大量的下載,通過FileInputStream方式下載對服務器的壓力還是挺大的. 如果可以,直接把文件放到web目錄下,直接由web服務器進行處理. 另外,既然是文件下載,一定牽扯到服務器帶寬的占用,建議還是把下載分流到其他的ip上去.我前公司的下載也是采用了這種方式. |
|||||||||
返回顶楼 | |||||||||
发表时间:2010-03-06
谢谢你的回复。
如果用<a href 会让服务器端目录结构直接暴露在外边。如果将下载目录放在WEB-INF中,则安全性太高,外界无法直接连到文件。 如果在架构层面上用上同步令牌,可以在一定程度上解决这个问题 |
|||||||||
返回顶楼 | |||||||||