`
rainsilence
  • 浏览: 158961 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

(原)download后回调刷新页面思路

阅读更多
企业级应用中,经常有要下载***文件的功能。为了减少服务器负担。经常在按下提交按钮的时候,让整张页面处于不可用的状态,以减少重复提交。现在比较流行的做法是用一个大的DIV罩住整个页面。等刷新的时候,DIV因为没有加载,所以页面复原。

这个时候,问题就来了。

看以下代码
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种状态
loading     Object is loading its data.
loaded      Object has finished loading its data.
interactive User can interact with the object even though it is not fully loaded.
complete    Object is completely initialized.

当执行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,所以不用担心重复刷新。
分享到:
评论
2 楼 rainsilence 2010-03-06  
谢谢你的回复。

如果用<a href 会让服务器端目录结构直接暴露在外边。如果将下载目录放在WEB-INF中,则安全性太高,外界无法直接连到文件。

如果在架构层面上用上同步令牌,可以在一定程度上解决这个问题
1 楼 ming500 2010-03-06  
好復雜哦。
提供的是下載功能,直接通過<a href='文件url連接'>方式指向文件的url給用戶進行下載不就好了嗎?

如果是大量的下載,通過FileInputStream方式下載對服務器的壓力還是挺大的.
如果可以,直接把文件放到web目錄下,直接由web服務器進行處理.

另外,既然是文件下載,一定牽扯到服務器帶寬的占用,建議還是把下載分流到其他的ip上去.我前公司的下載也是采用了這種方式.

相关推荐

    PanDownload 网页复刻版 百度网盘不限速下载带后台PHP源码

    PanDownload 网页复刻版,PHP 语言版 ...通过curl获取网盘文件信息,处理后显示在网页中。通过api接口以及SVIP账号的Cookie(BDUSS)获取高速下载链接。 本质就是用会员账号获取下载地址并发送给访客。

    不用刷新页面的文件上传和下载

    用起都还可以,不刷新页面 用起都还可以,不刷新页面用起都还可以,不刷新页面 用起都还可以,不刷新页面用起都还可以,不刷新页面 用起都还可以,不刷新页面用起都还可以,不刷新页面 用起都还可以,不刷新页面

    最简单的下拉刷新

    最简单的下拉刷新 什么都不用改 直接在listview外面加一个头就行 布局 代码 都不用改 另外为了节约流量没有传包 自己加一下jar包就能运行了

    当析构函数遇到多线程── C++ 中线程安全的对象回调

    编写线程安全的类不是难事,用同步原语...原始 PPT 可从 http://download.csdn.net/source/1982430 下载。 本文读者应具有 C++ 多线程编程经验,熟悉互斥器、竞态条件等概念,了解智能指针,知道 Observer 设计模式。

    PanDownload.rar

    PanDownload,解压缩,可直接使用,支持百度云资源下载。原理与 IDM 法类似,通过软件获取直链后调用 aria2 下载。 Pan Download 是一个吾爱的网友自己用 C++ 编写的。 开发windows桌面程序的选择比较多,c c++ ...

    php+html5(原代码改进升级版)多进程实现大文件无刷新上传,支持断点续传

    《php+html5(原代码改进)多进程实现大视频文件无刷新上传 》这个代码的改进升级版本,更新内容如下: 【2023.04.22】 1、修复大文件上传,上传到100%,合并文件这步容易失败(失败原因是文件越大合并耗时越长,...

    Free Download Manager Chrome 浏览器插件

    Free Download Manager 插件是一款免费好用的非常好用的多功能下载管理工具,适用于 Chrome 浏览器,该插件支持使网页和软件联动,当用户在网页上进行下载时将直接转到 Free Download Manager 之中。下载 Free ...

    网页视频chrome、firefox下载插件_Video-DownloadHelper_v7.3.9_VdhCoAppSetup_v1.5.zip

    谷歌chrome、火狐firefox网页视频下载插件_Video-DownloadHelper_v7.3.9_VdhCoAppSetup_v1.5.zip Video-DownloadHelper_v7.3.9.0.crx VdhCoAppSetup-1.5.0.exe

    WordPress 博客下载插件Download Monitor

    4.启用插件后,在左侧的设置下面会多出一个Download选项卡 5.Add New是添加下载文件 Download Monitor插件使用: 1.在Download选项卡下点击Add New进入下载文件添加页面 2.Title (required):下载文件的名称...

    网页视频下载插件_Video-DownloadHelper_v7.3.9_VdhCoAppSetup_v1.5.zip

    网页视频下载插件_Video-DownloadHelper_v7.3.9_VdhCoAppSetup_v1.5.zip Video-DownloadHelper_v7.3.9.0.crx VdhCoAppSetup-1.5.0.exe 腾讯课堂课程怎么用PC端下载.pdf

    Video DownloadHelper的合作安装应用

    Video-download-helper Video DownloadHelper的合作安装应用 No such native application net.downloadhelper.coapp

    Internet Download Manager破解版

    安装步骤:解压后点idman607.exe安装完成后,再打开解压后的IDM文件里的crack文件 然后按自己的系统运行reg文件如果是32位系统运行32位的reg 一直点是。然后把Patch.exe文件 复制到Internet Download Manager的根目录...

    VideoDownload合作安装应用HelperCompanionApp1.3 YLing.rar

    VideoDownload合作安装应用HelperCompanionApp1.3

    download software

    download software. welcome to download it

    原生JS写法精简倒计时(时分秒)

    * var test = new JJCountdown(计时总时间, 显示计时dom_id, 回调函数).show(); // output hh:mm:ss 00:00:00 * var test = new JJCountdown(计时总时间, 显示计时dom_id, 回调函数).show('m'); // output mm:ss ...

    Free Download Manager 5

    Free Download Manager是一个完全免费的多功能的下载和管理工具。...Free Download Manager 是一个强大的下载工具,支持多线程分割下载,支持定时下载和定时挂断连接,下载完成后断开连接或关闭计算机。

    2021美赛E题思路

    2021年美赛E题思路,免积分给大家分享,有需要的同学可以自取

    download_prerequisites.zip

    再升级gcc的时候,有时候会让我们下载依赖...然后使用tar命令解压放在gcc目录即可(我这里是升级gcc9.2.0, 所以放在gcc-9.2.0中) 也可以把压缩包放在目录后,再运行脚本contrib/download_prerequisites 会自动帮你解压

    CTF-misc中的F5刷新可以使用到的工具

    F5触发的HTTP请求的请求头中通常包含了If-Modified-Since 或 If-None-Match字段,或者两者兼有。CTRL+F5触发的HTTP请求的请求头中没有上面的那两个头 所以说你非常需要此工具!!!!!

Global site tag (gtag.js) - Google Analytics