以Web方式下载数据有多种场景:

1.服务端本身已经存在文件,此时只需要一个文件访问地址即可下载,比如:将文件URL设置为<a>标签的href属性即可,点击<a>标签就能立即触发浏览器下载文件,此时无需单独设置下载提示信息。

2.下载的文件在服务端并不存在,而是需要查询数据库等才能获取,这种方式无法直接在客户端设置一个文件访问URL,通常是以流式方式下载数据,这就是本篇博文要阐述的情景。

在大多数需要以流方式下载/导出文件的场景,从客户端发出请求,到浏览器端开始下载文件这一段间隔里,是不会有任何提示的,查看网络请求也是处于“Pending”状态的。

甚至有时候因为服务端查询数据耗时慢等问题会让用户误以为没有触发下载,于是又重复点击按钮,在导出大量数据的场景,这可能会加剧服务端的处理负担。

实际上,这却又是一个常见且普遍的问题。

之所以会出现这样的情况,就是因为当我们在浏览器端点击“下载/导出”按钮的时候没有给予用户一个明确的提示信息,或者说没有通过一种有效的手段来防止用户出现重复点击的情况。

那么对于这种以流式方式下载文件的情况,又该如何来实现当用户点击按钮后到浏览器出现下载提示这段时间给予用户一个明确的提示呢?

有一篇博文web程序下载文件添加等待加载效果阐述了使用iframe框架来实现这一功能,但经过实验并未成功。

直到看到另一篇博文前后端分离,前端获取文件流下载文件介绍的方式,经过实验发现,这种方式确实有效。

于是把该博文介绍的方式以一个完整的示例(使用EasyExcel导出表格)整理出来,提供给大家参考(基于Chrome浏览,版本:103.0.5060.134)。

展示效果如下:

服务端核心代码:

// 以流的方式下载文件
@RequestMapping("/download")
public String download(HttpServletRequest request, HttpServletResponse response,
@RequestParam("name") String name,
@RequestParam("age") int age) throws IOException {
System.out.println(String.format("name:%s, age:%s", name, age));
String fileName = URLEncoder.encode(String.format("%s_%s.xlsx", "导出数据", System.currentTimeMillis()), "UTF-8");
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
response.addHeader("filename", fileName); // 注意:这里一定要在响应消息头中设置下载文件名
response.setContentType("application/octet-stream; charset=UTF-8");
try {
// 模拟查询数据耗时
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
EasyExcel.write(response.getOutputStream(), SubjectExport.class).sheet("sheet").doWrite(dataList);
return null;
}

前端代码:

<html>
<body>
<div>
<form id="paramForm">
<input type="hidden" name="name" value="zhangsan" />
<input type="hidden" name="age" value="12" />
</form>
</div>
<div>
<button id="btnDownloadXhr">导出</button>
</div>
</body>
<script type="text/javascript" src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://cdn.bootcss.com/jquery.blockUI/2.66.0-2013.10.09/jquery.blockUI.min.js"></script>
<script type="text/javascript">
$(function(){
$("#btnDownloadXhr").click(function () {
downloadXhr();
})
}) function downloadXhr() {
var url = "/download";
var param = $("#paramForm").serialize();
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
xhr.responseType = "blob";
xhr.onload = function () {
console.log("加载完毕");
$.unblockUI();
if (xhr.status === 200) {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob);
var filename = decodeURI(this.getResponseHeader('filename'));
reader.onload = function (e) {
var a = document.createElement('a');
a.download = filename;
a.href = e.target.result;
//兼容firefox
$('body').append(a);
a.click();
$(a).remove();
}
}
};
xhr.send(param);
console.log("正在加载数据...")
$.blockUI({
message: "正在加载数据..."
});
}
</script>
</html>

完整示例代码地址:test-web-downloadtip,可以直接下载下来在本地运行。

【参考】

https://blog.csdn.net/qq_40527797/article/details/122813537 springBoot+JSP搭建项目

https://easyexcel.opensource.alibaba.com/ Easy Excel

https://blog.csdn.net/fgx_123456/article/details/79603455 web程序下载文件添加等待加载效果

https://blog.csdn.net/w139074301/article/details/121786052 前后端分离,前端获取文件流下载文件

Web流式下载数据时展示提示信息的更多相关文章

  1. 流式大数据计算实践(1)----Hadoop单机模式

    一.前言 1.从今天开始进行流式大数据计算的实践之路,需要完成一个车辆实时热力图 2.技术选型:HBase作为数据仓库,Storm作为流式计算框架,ECharts作为热力图的展示 3.计划使用两台虚拟 ...

  2. 流式大数据计算实践(6)----Storm简介&使用&安装

    一.前言 1.这一文开始进入Storm流式计算框架的学习 二.Storm简介 1.Storm与Hadoop的区别就是,Hadoop是一个离线执行的作业,执行完毕就结束了,而Storm是可以源源不断的接 ...

  3. 精讲RestTemplate第6篇-文件上传下载与大文件流式下载

    本文是精讲RestTemplate第6篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...

  4. 流式大数据计算实践(5)----HBase使用&SpringBoot集成

    一.前言 1.上文中我们搭建好了一套HBase集群环境,这一文我们学习一下HBase的基本操作和客户端API的使用 二.shell操作 先通过命令进入HBase的命令行操作 /work/soft/hb ...

  5. 流式大数据计算实践(2)----Hadoop集群和Zookeeper

    一.前言 1.上一文搭建好了Hadoop单机模式,这一文继续搭建Hadoop集群 二.搭建Hadoop集群 1.根据上文的流程得到两台单机模式的机器,并保证两台单机模式正常启动,记得第二台机器core ...

  6. 流式大数据计算实践(7)----Hive安装

    一.前言 1.这一文学习使用Hive 二.Hive介绍与安装 Hive介绍:Hive是基于Hadoop的一个数据仓库工具,可以通过HQL语句(类似SQL)来操作HDFS上面的数据,其原理就是将用户写的 ...

  7. 流式大数据计算实践(4)----HBase安装

    一.前言 1.前面我们搭建好了高可用的Hadoop集群,本文正式开始搭建HBase 2.HBase简介 (1)Master节点负责管理数据,类似Hadoop里面的namenode,但是他只负责建表改表 ...

  8. 流式大数据计算实践(3)----高可用的Hadoop集群

    一.前言 1.上文中我们已经搭建好了Hadoop和Zookeeper的集群,这一文来将Hadoop集群变得高可用 2.由于Hadoop集群是主从节点的模式,如果集群中的namenode主节点挂掉,那么 ...

  9. Java 使用流读文本数据时乱码 解决方法

    一.问题描述 当我使用FileReader读取文本文件里的汉字时,读出来的是乱码.但为什么字符是正常的呢??? 二.原因探究 其根本原因在于编码标准不同.汉字采用gbk,而idea使用UTF-8.gb ...

  10. ASP.NET Core SignalR中的流式传输

    什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时 ...

随机推荐

  1. [转帖]Lightning 实操指南

    2.2.2 Lightning 实操指南 这一节将介绍如何使用 Lightning 导入数据的实操 2.2.2.1 TiDB Lightning 快速开始 注意 TiDB Lightning 运行后, ...

  2. [转帖]分析redis 大key

    http://www.lishuai.fun/2023/05/05/redis-bigkey/#/%E5%AE%89%E8%A3%85 redis-rdb-tools 是一个 python 的解析 r ...

  3. [转帖]Jmeter 压测中配置https证书

    本文章 主要介绍证书的获取.处理.配置到jmeter中. 1. 获取证书 首先:谷歌浏览器 打开网站,点击 地址栏的锁(表示https),选择 "证书"---"隐私.搜索 ...

  4. [转帖]GC 日志

    https://www.xjx100.cn/news/188814.html?action=onClick 垃圾回收器的发展历史 1999年:随JDK1.3.1一起来的串行方式Serial GC(第一 ...

  5. vue关于通过下标更改数组的理解

    案例1:通过下标更改数组失败 <template> <div> <el-button @click="handlerMe2"> 改变 arr & ...

  6. axios文件上传和 Content-Type类型介绍

    Content-Type的作用是什么? Content-Type: 用于在请求头部指定资源的类型和字符编码. 请求头中的content-type,就是 B端发给S端的数据类型描述 . 即告诉服务器端, ...

  7. 【小实验】golang中的字节对齐

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 使用golang来调用SIMD指令,发现程序崩溃了: __ ...

  8. 【JS 逆向百例】复杂的登录过程,最新WB逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 本次的逆向目标是 ...

  9. vim 从嫌弃到依赖(7)——可视模式

    vim 的可视模式下可以选择一个区域,然后针对区域进行操作.可视模式有点类似于在其他编辑器上使用鼠标选中一块区域然后针对区域进行操作. vim中有3种可视模式,分别用来处理不同范围的文本: 处理字符的 ...

  10. 4.5 Windows驱动开发:内核中实现进程数据转储

    多数ARK反内核工具中都存在驱动级别的内存转存功能,该功能可以将应用层中运行进程的内存镜像转存到特定目录下,内存转存功能在应对加壳程序的分析尤为重要,当进程在内存中解码后,我们可以很容易的将内存镜像导 ...