我们知道在 Chrome、Firefox 等浏览器可以查看 PDF 文件,不需要额外安装什么插件,这是由于 pdf.js 被预置到了这些浏览器中。
pdf.js 是一款使用 HTML5 Canvas 安全地渲染 PDF 文件以及遵从网页标准的网页浏览器渲染 PDF 文件的JavaScript库。Mozilla基金会主导。
pdf.js 可以作为浏览器或网站的一部分运行。原本是一个Firefox扩展[2],自2012年开始,它被纳入Mozilla Firefox(15版本)[3][4],并从2013年开始默认启用(19版本)成为基本功能[5][6] 。它还是ownCloud的一部分,并可用作Chrome、Chromium[7]、Firefox for Android[8]、Pale Moon[9]及SeaMonkey[10]的附加组件。
以上引用摘自维基百科 PDF.js。
在手机浏览器中,如 QQ浏览器、UC 浏览器、Safari 浏览器,打开一个 PDF 是一个下载页面,无法查看。分别使用手机浏览器和桌面浏览器查看 pdf 文件。
手机端浏览器想要查看 PDF 文件可以使用 PDF.js 插件。在线演示地址。
一、下载 PDF.js 插件
下载PDF.js插件。如果是下载的压缩包,解压之后,将整个文件夹拷贝到项目中。
二、测试 PDF 文件是否可查看
在服务器中打开 /pdfjs-2.5.207-dist/web/viewer.html 文件。通过 http-server 运行 /web/viewer.html 文件。
http-server -p 10086 以 10086 端口启动服务器。打开手机浏览器访问:http://ip:10086/pdfjs-2.5.207-dist/web/viewer.html (ip改成 127.0.0.1 或本机 ip)。
三、项目中测试 PDF 是否可查看
在 /pdfjs-2.5.207-dist/web/ 下添加一个 flask入门教程.pdf 和新增 pdf-viewer.html
注意
在项目中测试时,我们是以 /web/viewer.html 文件为基础,后接 ‘?file=’,再接 pdf 文件地址。注意这里的 pdf 文件和 html 文件的相对路径。
打开手机浏览器访问:http://ip:10086/pdfjs-2.5.207-dist/web/pdf-viewer.html (ip改成 127.0.0.1 或本机 ip)。
四、跨域访问 PDF
通常,我们访问的 PDF 不是一个静态文件,而是接口返回一个 PDF 存放地址,这时,使用 ./viewer.html?file=${pdfUrl} 匹配地址会存在跨域问题。
我们可以使用 webpack 开发服务器中的代理支持来把特定的 URL 转发给后端服务器。以angular工程为例
只要传入 –proxy-config 选项就可以了。 比如,要把所有到 http://localhost:10086/file 的调用都转给运行在 http://192.168.8.184:7600/file 上的服务器,可采取如下步骤。
-
在项目的 src/ 目录下创建一个 proxy.conf.json 文件。
-
往这个新的代理配置文件中添加如下内容:
1 2 3 4 5 6 7 8 9 |
<pre class="inline:true class:hljs bash decode:1 " >... <span class="hljs-string">"/file"</span>: { <span class="hljs-string">"target"</span>: <span class="hljs-string">"http://192.168.8.184:7600"</span>, <span class="hljs-string">"secure"</span>: <span class="hljs-literal">true</span>, <span class="hljs-string">"changeOrigin"</span>: <span class="hljs-literal">true</span>, <span class="hljs-string">"logLevel"</span>: <span class="hljs-string">"debug"</span> } ... |
- 在 CLI 配置文件 angular.json 中为 serve 目标添加 proxyConfig 选项:
1 2 3 4 5 6 7 8 9 10 |
<pre class="inline:true class:hljs perl decode:1 " >... <span class="hljs-string">"architect"</span>: { <span class="hljs-string">"serve"</span>: { <span class="hljs-string">"builder"</span>: <span class="hljs-string">"@angular-devkit/build-angular:dev-server"</span>, <span class="hljs-string">"options"</span>: { <span class="hljs-string">"browserTarget"</span>: <span class="hljs-string">"your-application-name:build"</span>, <span class="hljs-string">"proxyConfig"</span>: <span class="hljs-string">"src/proxy.conf.json"</span> }, ... |
- 要使用这个代理选项启动开发服务器,请运行 ng serve 命令。
五、其他问题
- pdf 访问抛错
当跨域访问时,pdf.js 会抛出错误 file origin does not match viewer's,这时只需要将 viewer.js 中相应提示注释即可:
- Angular 防止 XSS 攻击安全问题
当给 <iframe[src]=”someValue”> 中绑定一个 URL,someValue 将会被净化, 以防范攻击者注入 javascript: 之类的 URL,并借此在网站上执行代码。
可使用 bypassSecurityTrustResourceUrl 绕过安全检查,并信任给定的值是一个安全的资源 URL。也就是说该地址可以安全的用于加载可执行代码,比如 <script src> 或 <iframe src>。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<pre class="inline:true class:hljs kotlin decode:1 " >... <iframe id=<span class="hljs-string">"iframe"</span> [src]=<span class="hljs-string">"iframeSrc"</span> width=<span class="hljs-string">"100%"</span> height=<span class="hljs-string">"100%"</span> frameborder=<span class="hljs-string">"0"</span> ></iframe> ... ... <span class="hljs-keyword">constructor</span>( <span class="hljs-keyword">private</span> sanitizer: DomSanitizer, ) {} <span class="hljs-keyword">this</span>.viewerUrl = <span class="hljs-string">'../../../../assets/pdfjs-2.5.207-dist/web/viewer.html'</span>; <span class="hljs-keyword">this</span>.iframeSrc = <span class="hljs-keyword">this</span>.sanitizer.bypassSecurityTrustResourceUrl(<pre class="inline:true decode:1 " >${<span class="hljs-keyword">this</span>.viewerUrl}?file=/${<span class="hljs-keyword">this</span>.pdfUrl} |
);
…
浏览量: 22