文件下载不能使用ajax的替代解决方案

前天我们决定优化一下之前使用系统的导出excel和pdf文件功能,由于有时候数据量比较大,服务器查询数据和生成文件的事件可能会比较长,于是我们决定在前台页面加一个”数据处理中”的提示,在此期间不让用户重复操作,当文件生成好了之后开始下载,并让用户可以继续操作。很简单的需求,就是对需要较长时间的操作加等待提示,防止用户多次操作而已,但实际上还花了些时间才搞定。

  • 分析

正常情况这种时候首先想到的就是用ajax向服务器提交数据,并限制用户的页面操作,得到服务器返回的成功状态之后再解除操作限制就行了,但是后来发现ajax不支持流类型数据,而下载文件就是用的流,所以这里只能使用submit,而submit在这里就有个问题,我们怎么才能知道服务器什么时候已经准备好了要下载的文件呢?也就是我们什么时候确定可以解除对用户的操作限制?所以这个问题就变成了得到服务器的状态反馈。这里提供两个方案:

  • 第一种

比较容易想到。既然ajax不能处理流,那就不处理,先用ajax向后来发送请求,后台把文件生成好之后存放到服务器上某个目录,然后把路径跟文件名传回到前台页面,前台页面接收到之后就可以根据路径和文件名进行下载并解除页面操作限制了,即把生成文件跟下载文件操作分开,生成文件部分用ajax获取状态、下载使用普通的submit。

  • 第二种

由于一些其他的原因,我不得不让文件的生成跟下载连续执行;所以只好使用第二种方法。第二种就是不通过ajax的方式提交数据,仍然直接submit数据到后台,后台处理完成之后往cookie里面写值,而前台通过不停读取cookie中的值,如果得到了服务器写入的值,就证明后台已经处理完了,这时候就可以接触页面操作限制了。
思路出来之后,正式做的过程中还遇到了几个问题,因为之前也没太注意这方面的问题;第一个,在submit之后,马上紧跟着一段循环读取cookie的代码,结果发生神奇的事情,后台根本就没有接收到请求,也就是说submit并没有成功,估计submit操作也是个异步操作,但是由于紧接着的循环读取cookie操作,占用了执行线程,从而使得submit操作一直没有真正的发出去,请求发不出去cookie就永远读不到值,这就互相等待了。所以后来我加了个延时执行,让循环延时半秒再执行(注意:延迟函数中调用循环检测,而不是在循环检测中调用延迟函数),然后后台服务器就能接受到请求了。然后我们又遇到了第二个问题,每次服务器写入cookie之后会被浏览器缓存起来,然后下一次浏览器循环读取的时候马上就能读到cookie值,所以我在服务器端的cookie值每次都加上一个随机数,保证每次的值都不一样(至少跟上一次的值不一样),然后服务器读取到cookie值之后每次进行判断,从第一次开始,把每次读取到cookie中的值保存起来,然后每次读到的值跟上一次的值做比较,知道跟保存起来的值不一样才说明得到了这次服务器返回的值,然后进行后续接触页面操作限制等操作,并把最新的值更新为比较值。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页