引言:最近在做微信小程式和手機端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.pageNum
page = page > 1 ? page - 1 : this.pageTotalNum
this.pageNum = page
},
// 下一頁函式
nextPage() {
var page = this.pageNum
page = page < this.pageTotalNum ? page + 1 : 1
this.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系統中沒有這個問題,
經過以上的嘗試后,最后決定基于vue.js來實作業務要求,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/382908.html
標籤:其他
上一篇:Flutter三棵樹理解
下一篇:某跨境出口電商APP引數解密
