PDF.JS飞书预览

868 阅读2分钟

背景

时间:2022-06

最近有一个需求,希望用户在飞书手机端点开pdf链接的时候,预览pdf,而不是直接触发下载,前端实现。

ps:目前飞书端使用 window.open 都是直接触发下载

实现方式

前端做一个单独预览pdf的页面,根据地址栏的参数来显示预览功能。

技术选型

pdf.js

相关链接

pdf.js官网pdf.js的github地址

技术难点

1,pdf.js的使用方式

  1. 官网下载pdf文件包,解压后文件结构如下:
pdfjs
   |
   |--build
   |--web
        | - ...
        |- viewer.html
        |- viewer.js
  1. 启动本地服务,我使用的是 anywhere
// 在pdfjs文件夹下
anywhere -p 9090
  1. 打开viewer.html文件,会看到一个默认预览状态的pdf
  2. 修改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浏览器....就很无语...