背景
时间:2022-06
最近有一个需求,希望用户在飞书手机端点开pdf链接的时候,预览pdf,而不是直接触发下载,前端实现。
ps:目前飞书端使用 window.open 都是直接触发下载
实现方式
前端做一个单独预览pdf的页面,根据地址栏的参数来显示预览功能。
技术选型
pdf.js
相关链接
技术难点
1,pdf.js的使用方式
- 官网下载pdf文件包,解压后文件结构如下:
pdfjs
|
|--build
|--web
| - ...
|- viewer.html
|- viewer.js
- 启动本地服务,我使用的是
anywhere
// 在pdfjs文件夹下
anywhere -p 9090
- 打开
viewer.html文件,会看到一个默认预览状态的pdf - 修改
viewer.js文件,将defaultOptions.defaultUrl.value设为空(此时viewer.html页面为空)
defaultOptions.defaultUrl = {
value: "compressed.tracemonkey-pldi-09.pdf", // 设为 value: ""
kind: OptionKind.VIEWER
};
4,在viewer.html页面地址栏添加参数 ?file=xxxx, xxxx代表需要预览的pdf文件地址。
注意!默认情况下,需要pdf地址与viewer.html同源
地址示例:
http://172.17.5.106:9090/web/viewer.html?file=http://172.17.5.106:9090/web/compressed.tracemonkey-pldi-09.pdf
2,手机端兼容性问题的解决
学会使用pdf.js后,会发现在手机端的飞书上会出现安卓机打不开页面,部分ios机样式异常的问题。
原因:viewer.js等文件中出现了const 、()=> {}、?、??等新语法, 飞书自带浏览器版本较低,不支持此类语法。
解决思路: 将viewer.js 等文件转码为es5。这里推荐去pdf.js的github地址下载源码,根据官方打包流程,编译出需要的资源。
最终实现方式
1,生成源码包
$ git clone https://github.com/mozilla/pdf.js.git
$ cd pdf.js
$ npm install -g gulp-cli
$ npm install
$ gulp generic-legacy // 注意!不是执行 generic, 而是 generic-legacy
此时生成build文件夹,其中build/generic-legacy文件夹即为所需资源包。
可以看到,新的资源包内的代码均为编译后的。
到这一步,已经达到飞书浏览器的兼容性要求了。
扩展
仔细查看新生成的资源包,会发现包里面还是会有globalThis,以及一些新方法未转码。
兼容globalThis代码如下
!function(t){function e(){var e=this||self;e.globalThis=e,delete t.prototype.T}"object"!=typeof globalThis&&(this?e():(t.defineProperty(t.prototype,"T",{configurable:!0,get:e}),T))}(Object);
兼容新方法,可以引入 polyfill.js。
ps:polyfill文件如果不知道去哪找的话,这里提供一个方案:使用npm i @babel/polyfill,取node_modules/@babel/polyfill/dist/polyfill.min.js.
其他
顺便发现:就算兼容到这个程度,发现还是兼容不了pc端/手机端的uc浏览器....就很无语...