`
rainsilence
  • 浏览: 160585 次
  • 性别: 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上去.我前公司的下載也是采用了這種方式.

相关推荐

    回调小案例

    本案例“回调小案例”将探讨两种常见的回调实现方法,并通过接口和回调的概念来增强我们的理解。 首先,我们需要了解什么是回调。回调是一种编程策略,其中函数或方法A作为参数传递给另一个函数或方法B,当B执行到...

    最简单的下拉刷新

    下拉刷新功能是移动应用和网页中常见的交互设计,它允许用户通过向下拉动内容区域来刷新数据。在Android开发中,实现下拉刷新通常需要对ListView或者RecyclerView进行扩展,但根据给定的描述,这里介绍的方法是相对...

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

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

    android中DownloadManager实现版本更新,监听下载进度实例

    1. 创建一个继承自ContentObserver的派生类,并重载onChange方法,以便在数据发生变化时处理回调。 2. 为特定的Uri注册ContentObserver派生类的实例,使用registerContentObserver方法。当对应的Uri内容发生变化时,...

    Video DownloadHelper 插件

    当在支持的网页上播放媒体内容时,DownloadHelper会自动检测到并显示在浏览器的右下角,点击图标即可选择合适的格式和质量进行下载。 此外,Video DownloadHelper还允许用户自定义下载设置,如设置默认存储位置、...

    Video DownloadHelper的合作应用安装

    当用户访问包含可下载视频的页面时,该扩展会在浏览器工具栏上显示一个图标,点击后会显示可用的视频格式和质量供用户选择。 合作应用,或VdhCoAppSetup-1.6.3.exe,可能是Video DownloadHelper为了增强其功能或者...

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

    在IT行业中,文件上传和下载是网页应用中的常见功能,特别是在云存储、文件分享和协作平台等场景下。"不用刷新页面的文件上传和下载"技术使得用户可以在不中断当前浏览体验的情况下完成文件操作,提高了交互性和用户...

    Free Download Manager Chrome 浏览器插件

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

    PanDownload.rar

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

    Python3-异步进程回调函数(callback())介绍

    可以看到,当`download`函数运行结束后,控制权回到了主进程,然后调用`alterUser`回调函数,处理`download`的返回结果。 此外,代码还展示了如何在多线程环境中使用回调函数。`thread.start_new_thread`用于启动一...

    httpDownload

    这些事件的回调函数可以帮助我们实现更复杂的业务逻辑,比如显示进度条或者处理错误。 总的来说,`HttpDownload`是C#网络下载的一个强大工具,它提供了许多实用的功能,包括超时控制、队列管理以及数据解压缩,极大...

    DownloadManager, 一个下载框架/a download library.zip

    5. **错误处理**:当下载过程中遇到错误,如服务器无响应、网络错误等,DownloadManager 会尝试进行重试或者根据错误类型向开发者发送回调,以便进行相应的处理。 6. **通知用户**:在Android系统中,Download...

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

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

    网页视频下载插件_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

    火狐download helper 插件 vdhcoapp1.6.0

    - **自动检测媒体资源**:当用户浏览网页时,Download Helper会自动检测并列出页面上所有可下载的媒体文件,无需手动复制链接。 - **多样化下载格式**:支持多种格式的资源下载,如MP4、FLV、WebM、MP3等,涵盖了大...

    downloadhelper

    "downloadhelper"是一款专为IE浏览器设计的视频和音乐下载插件,它的主要功能是让用户在浏览网页时能够轻松、快捷地下载媒体内容,而无需依赖其他第三方软件。这款插件极大地提升了用户在互联网上获取多媒体资源的...

    Video DownloadHelper Companion App 1.2.4.rar(亲测可用)

    在浏览网页时,如果页面包含可下载的视频,DownloadHelper图标会高亮显示,点击后出现的菜单会列出所有可下载的媒体文件,选择你需要的文件,然后点击下载。对于有特定需求的用户,还可以通过Companion App进行更...

    Video DownloadHelper.rar

    - 安装后,浏览器的工具栏会出现Video DownloadHelper的图标,表示已成功安装。 3. **Video DownloadHelper使用步骤** - **开启扩展**:打开一个包含视频的网页,确保Video DownloadHelper的图标是活动的(通常为...

Global site tag (gtag.js) - Google Analytics