一,需求背景
在.NetCore新版项目中,针对电子文件在线浏览的实现方案做出了调整,由于需要支持跨平台,因此摒弃掉原来使用的第三方控件的方式。目前对于PDF文件的在线浏览采用的开源JS框架PDF.JS。它功能还是比较强大的,支持常用的PDF预览效果,文件下载和打印等等功能。
但如果PDF文件较大或者页数过多时,会发现PDF.JS需要等待很长时间才能将整个文件加载出来,这样用户的使用体验是不佳的,因为较长时间迷茫的等待,并且没有任何进度条提醒,会给人一种不知道是单纯的加载文件慢还是加载遇到了错误?到底该不该继续等待加载?的感觉,以至于失去耐心。
那么如何解决这种“迷茫等待”的粗劣使用体验呢?PDF.JS瀑布流加载机制应运而生......
二,前端请求机制
PDF.JS用于浏览文件的自带html页面是viewer.html,因此浏览文件都是需要跳转到该页面。
PDF.JS加载文件是有两种方式的:
(1)如图2-1.png所示,该前台页面通过ajax请求后台接口,从而获得要浏览的文件的base64格式的字符串,然后通过JS的一系列转换,生成PDF.JS能识别的数据格式,最后再对DEFAULT_URL变量进行赋值即可。
(2)JS中直接通过对html中的<iframe>控件绑定地址链接到viewer.html页面,并且需要将要浏览的文件流作为file参数传递过去,而这个文件流参数是通过get请求后台返回文件流的接口来获取的。前台示例代码如下:
document.getElementById("if1").src = ‘/static/pdf/web/viewer.html?file=‘+encodeURIComponent(window.localStorage.getItem("rooturl")+‘/api/OnlineView/GetFileStreamPDF?syscode=‘+data.syscode+‘&unitsys=‘+this.$store.state.user.unit+"&username="+this.$store.state.user.name);
三,利弊对比
(1)上面第一种方式相当于把整个文件的全部数据通过一次接口请求全部获取并返回给前台PDF.JS进行渲染加载。
这种方式的优点是:前后台请求次数少只有一次,保留了文件整体性,文件的各个页会同时加载出来;
不过该方式缺点也很明显:如果文件很大或页数很多时,需要等待很长时间才能加载出文件;
(2)上面第二种方式相当于把一个文件进行分段请求和加载,PDF.JS也是支持这种加载方式的。
这种方式的优点是:可以让用户更快的先看到一部分页面,剩余页面的加载进度也可以通过界面上的加载进度条直观的体现出来。不但可以更快的浏览到一些文件页面,而且还能对加载的整体进度做到心里有数;
该方式的缺点是:需要很多次的频繁请求后台,虽然可以让用户提前浏览到一些页面,但是从文件开始加载到最终完成加载所用到的时间总和一定是要多余第一种方式的。而且分段加载的先后顺序不能很好的控制,有可能出现文件的最后一页加载完成,但是中间的某些页还没有加载出来的现象;