实现微信小程序和手机app(基于vue)PDF预览功能
引言:最近在做微信小程序和手机端app开发(基于vue),实现一个pdf预览功能。
- 需求:点击pdf列表,跳转到预览pdf页面,页面上强制阅读10s后,显示一个按钮返回,更新阅读状态;
- 要求:不能调用本地浏览器预览,不能让用户下载pdf,强制阅读10s后才可返回;
- 准备:pdf在线文档:“http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf”
1.微信小程序端
- 方式一:webview
<web-view src="http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf" ></web-view>
运行结果:
分析:
- 上述结果是在ios系统上运行的,pdf可以正常显示;
- 在android系统上,解析失败,一直显示空白界面;
- 原因:ios可以自动解析pdf,安卓系统则解析不了;
- 补充:在webview标签上显示按钮,相信做过微信小程序开发的都了解webview标签会默认占满全屏,覆盖掉其他组件,这个时候如果我们想加一个按钮就可以用cover-view标签来实现,具体实现大家可以自己去探索。
总结:使用webview标签在系统上兼容性并不好,不能控制下载状态,而且在阅读状态上只能做到“假控制”。
2.手机app端(vue)
1. 使用 iframe、embed、新窗口打开
<iframe class="iframe" src="http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf"></iframe>
<embed class="iframe" src="http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf">
优点:简单,支持大部分 PC 浏览器(IE 不支持)。跨域资源同样可以(无需 cors)
缺点:不支持移动端浏览器,不支持 IE 等低版本浏览器。样式无法自定义。
2. 使用vue中的组件vue-pdf
安装:打开命令行,直接使用npm或者yarn安装
npm install --save vue-pdf
<template><div class="pdf_wrap"><div class="pdf_list"><pdf :src="src" style="width: 100%" ref="pdf"> </pdf></div></div>
</template><script>import pdf from 'vue-pdf'export default {name: 'myTestOne',components: {pdf},data () {return {src: 'http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf',}},methods: {}}
</script>
<style scoped>.pdf_wrap {background: #fff;height: 100vh}.pdf_list {height: 80vh;overflow: scroll;}</style>
当你运行这段代码时(在pdf链接没过期的情况下),你会惊奇地发现,会出现跨域问题,并报出以下错误:
解决方案一
你需要联系你的后端小伙伴,因为PDF 文件作为静态资源放在 nginx服务器中。
在 nginx.conf 中设置:
add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Origin $http_origin;
完整配置如下:
server {listen 80;server_name localhost;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Origin $http_origin;location / {root pdf;index index.html index.htm;}
}
解决方案二(存在问题,后期研究)
和vue 接口请求解决跨域问题一样,在本地开发时同样通过 webpack的devServer去代理pdf预览的url(请求),其他环境(生成及测试)则让后端去解决。
解决开发环境pdf预览跨域问题就是在devServer中添加一个代理即可:
//vue.config.js
proxy: {//当pdf和数据接口不在同一个请求地址下时,为pdf预览追加一个代理"/pdf": {target:"http://cn.createpdfonline.org/pdffiles",changeOrigin: true,pathRewrite: {'^/pdf': ''}}}
运行结果如下:
重新保存项目,这个pdf就会显示在你的眼前,但是别高兴得太早,这个pdf只有一页,所以在这个基础上进行以下优化:
- 显示多页pdf
- 显示pdf总页数
- 实现一页一页翻pdf的功能
- 监控当前页面加载进度
代码实现(多页显示):
<template><div class="pdf_wrap"><div class="pdf_list"><pdf v-for="i in numPages" :key="i" :page="i" :src="url" style="width: 100%" > </pdf></div></div>
</template><script>import pdf from 'vue-pdf'export default {name: 'myTestOne',components: {pdf},data () {return {src: 'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf',numPages:1,url:''}},mounted: function() {this.getNumPages()},methods: {getNumPages() {this.url = pdf.createLoadingTask(this.src)this.url.promise.then(pdf => {this.numPages = pdf.numPages // 这里拿到当前pdf总页数})},}}
</script>
<style scoped>.pdf_wrap {background: #fff;height: 100vh}.pdf_list {height: 100vh;overflow: scroll;}</style>
结果展示:
该代码在pdfjsWrapper.js文件的第196行会报错,(偷摸给注释掉了)
//pdfRender.cancel().catch(function(err) {//emitEvent('error', err);//});
代码实现(单页展示,可翻页):
<template><div><div class="tools"><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="prePage" class="mr10"> 上一页</bk-button><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="nextPage" class="mr10"> 下一页</bk-button><div class="page">{{pageNum}}/{{pageTotalNum}} </div><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="clock" class="mr10"> 顺时针</bk-button><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="counterClock" class="mr10"> 逆时针</bk-button></div><pdf ref="pdf":src="url":page="pageNum":rotate="pageRotate"@progress="loadedRatio = $event"@page-loaded="pageLoaded($event)"@num-pages="pageTotalNum=$event"@error="pdfError($event)"@link-clicked="page = $event"></pdf></div>
</template>
<script>import pdf from 'vue-pdf'export default {name: 'Home',components: {pdf},data() {return {url: "http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf",pageNum: 1,pageTotalNum: 1,pageRotate: 0,// 加载进度loadedRatio: 0,curPageNum: 0,}},mounted: function() {},methods: {// 上一页函数,prePage() {var page = this.pageNumpage = page > 1 ? page - 1 : this.pageTotalNumthis.pageNum = page},// 下一页函数nextPage() {var page = this.pageNumpage = page < this.pageTotalNum ? page + 1 : 1this.pageNum = page},// 页面顺时针翻转90度。clock() {this.pageRotate += 90},// 页面逆时针翻转90度。counterClock() {this.pageRotate -= 90},// 页面加载回调函数,其中e为当前页数pageLoaded(e) {this.curPageNum = e},// 其他的一些回调函数。pdfError(error) {console.error(error)},}}
</script>
<style scoped></style>
结果展示:
总结:在实际测试中发现以下问题
- 场景:一个pdf列表,点击每个pdf预览;
- 结果:在ios系统中偶尔会出现白屏的状态,而在android系统中没有这个问题。
经过以上的尝试后,最后决定基于pdf.js来实现业务要求。
引言:经上面的测试,发现了以下问题:
- 兼容性不好
- 不适用多语言场景(不能共用一套)
- 会出现跨域问题
- 难于监控阅读状态
- 不能控制下载状态
在基于vue开发的移动项目中,如果预览的pdf数量不是很多的话,是可以使用 vue-pdf 的,因为在实际开发测试中,ios系统依次预览多个pdf文件会出现白屏的现象,android系统不会出现。但是此时也很难监控阅读状态,所以最后采用pdf.js来实现业务需求。
目录:
- 实现效果
- 1.下载pdfjs
- 2.放在项目中位置
- 3.在页面中使用
- 4.出现问题
- 5.更改源码
实现效果
1.下载pdfjs
官网:
2.放在项目中位置
为了减小打包体积,bulid文件夹中保留pdf.js和pdf.worker.js即可正常编译。
3.在页面中使用
在我的项目中,pdf文件是以url的形式提供的,我们在页面中放一个iframe,他的src属性等于到viewer.html的相对路径 '/pdfplugin/web/viewer.html?file=' ,file后拼接你的pdf的url就可以了。
代码实现:
<template><div><iframe :src="src" style="width: 100%;height: 100vh" ></iframe></div></template><script>export default {name: "myTestTwo",data(){return {url:'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf',src:''}},mounted() {this.getUrl();},methods :{getUrl:function () {this.src = '/pdfplugin/web/viewer.html?file=' + this.url}}}
</script><style scoped></style>
效果展示:
通过结果可以看出,pdf.js真的是很强大,我们可以按照需求来更改源码,实现自己想要的效果。
4.出现问题
- 跨域问题:可参考这篇文章,推荐让后端小伙伴添加配置。
- 当访问本地文件时,有可能会出现**
Not allowed to load local resource
**的问题,原因是谷歌浏览器禁止直接访问磁盘文件,在实际开发中,文件大多存在服务器中,如果个人想学习测试可以使用在线的pdf资源。 - 在使用viewer.html相对路径时有可能找不到正确路径,我之前的路径是
/public/pdfplugin/web/viewer.html?file=
,发现怎么也找不到文件,后来去掉了一层/public
,pdf就神奇的出来了。
5.更改源码(持续更新中)
实现微信小程序和手机app(基于vue)PDF预览功能相关推荐
- 微信小程序实现图片是上传、预览功能
本文实例讲述了微信小程序实现图片上传.删除和预览功能的方法,分享给大家供大家参考,具体如下: 这里主要介绍一下微信小程序的图片上传图片删除和图片预览 1.可以调用相机也可以从本地相册选择 2.本地实现 ...
- 小程序 | 微信小程序实现图片是上传、预览功能
效果图 index.wxml <!-- 打开截图 开始 --> <view class="imageContainer"><view class=&q ...
- 实现微信小程序和手机app远程控制51单片机控制L298N电机驱动器控制马达(ESP8266 AT89S52 http请求转串口通信系统 mqtt )
首先你有这样的8266 这种8266自身带2个按键和烧录芯片方便调试,综合性价比较高. 还有就是你需要有一个51单片机或者其他芯片都行.有了这2个芯片我们开始吧! 1.先看一段视频效果演示,再来介绍实 ...
- 【小程序模板】功能模块+仿vivo手机商城微信小程序+品牌手机APP购物网页模板
[小程序模板]功能模块+仿vivo手机商城微信小程序+品牌手机APP购物网页模板 源码简介与安装说明: 仿vivo手机商城微信小程序 品牌手机app购物网页模板源码下载. 小程序源码下载地址:(82条 ...
- 关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案
关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案 参考文章: (1)关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案 (2)https://www.cnblog ...
- 微信小程序saveFile,openDocument方法下载、预览pdf文件不能用本地应用打开(不能另存为)的问题
微信小程序saveFile,openDocument方法下载.预览pdf文件不能用本地应用打开(不能另存为)的问题 查看官方文档的openDocument()方法,发现加一个showMenu: tru ...
- 微信小程序与手机APP的区别
最近在研究论文选题,到底是做手机APP好还是尝试一下很火热的微信小程序呢?我收集整理了一些网上资料做参考.也在这里做个记录. 是什么? 微信小程序,简称小程序,是一种不需要下载安装即可使用的应用,它实 ...
- 微信小程序 android内存暂用,微信小程序与手机APP占用内存 流量消耗对比介绍
10年前的1月9日诞生了iPhone,今年的1月9日诞生了微信小程序,这无疑是2017年中国互联网圈的开年大事件.这几天,相信大家在网上到处都被微信小程序刷了屏,各种技术探讨.前景分析层出不穷,尤其是 ...
- MAC系统利用charles抓取微信小程序和手机APP数据包(http和https数据包)
本文中使用的是mac上的抓包工具charles进行抓包,手机是华为荣耀8 下载并安装Charles for Mac Charles for Mac(HTTP信息抓包工具) V4.2.5 苹果电脑版 要 ...
最新文章
- Linux下编译一个静态链接的程序的注意点
- ML:推荐给小白入门机器学习一系列书籍
- Intel Realsense 处理帧时报错:RuntimeError: null pointer passed for argument frame_ref
- c语言语法分析源程序,深入浅出编译原理-5-一个简单语法分析器的C语言实现
- HTTP 301 跳转和302跳转的区别
- shell 执行失败重试_Uipath 机器人总是运行失败怎么办?
- 大一萌新看过来,C语言学到什么程度,才能“毕业不失业”!
- linux查看文件时显示行号,linux中查看文件时显示行号
- ubuntu 分区_系统小技巧:迁移通过Wubi方式安装的Ubuntu系统
- android刷机工具mac版,苹果一键刷安卓!OS X版CM刷机工具发布
- jsonrpc-c编译
- Python下载Wyoming怀俄明大学探空数据(数据网址更新)
- win10系统安装教程(U盘PE+UEFI安装)
- MacBook Pro 上网很慢
- JAVA微服务架构视频教程
- free源码分析---1
- PMBOK2004版44个过程的工具和技术的总结
- 饿了么退货显示服务器异常,外卖配送异常订单如何处理?商家必看!
- VS2008 使用小技巧-------快捷键
- python操作Excel的5种常用方式