以(yǐ) web-view 嵌入在(zài)小程序中 h5 頁面,如何處理附件下載
發表時(shí)間:2021-1-5
發布人(rén):融晨科技
浏覽次數:286
前言
由于(yú)項目體積過大(dà),以(yǐ)至于(yú)分包後也(yě)逐步超過了(le/liǎo)小程序的(de)限制,所以(yǐ)将 h5 端的(de)頁面以(yǐ) web-view 的(de)方式嵌入了(le/liǎo)小程序。這(zhè)也(yě)産生了(le/liǎo)一些意料之(zhī)外的(de)問題,這(zhè)裏記一個(gè)關于(yú)文件預覽下載的(de)問題。
在(zài) h5 端中,針對圖片和(hé / huò)視頻會使用 img、video 标簽達到(dào)預覽的(de)效果,其餘的(de)文件類型會直接粗暴的(de)調用 window.open
的(de)方式打開,如果浏覽器能夠解析則預覽,不(bù)能解析浏覽器會默認下載。(這(zhè)裏有個(gè)問題,ios 的(de)手機對于(yú)不(bù)能識别的(de)文件會顯示亂碼)
嵌入小程序并配置了(le/liǎo)附件存儲的(de)業務域名之(zhī)後發現使用 android 手機調用 window.open
會出(chū)現白屏,ios 手機則沒有問題。
嘗試使用 iframe 标簽達到(dào)類似的(de)效果,但是(shì)在(zài)小程序中也(yě)是(shì)沒有效果的(de)。
解決的(de)方法
後面同事給了(le/liǎo)個(gè)思路,對于(yú)需要(yào / yāo) window.open
打開的(de)文件,直接跳轉到(dào)一個(gè)特定的(de)小程序原生頁面,借助小程序的(de) api 預覽文件。如果小程序環境也(yě)無法預覽的(de)文件,則使用小程序的(de) api 下載文件。
- h5 頁面的(de)處理
import wx from 'weixin-js-sdk'
if (
process.env.TARO_ENV === 'h5' &&
window.__wxjs_environment &&
window.__wxjs_environment === 'miniprogram'
) {
wx.miniProgram.navigateTo({
url: `/pages/file/index?
fileExt=${fileExt}
&tokenId=${tokenId}
&fileName=${fileName}
&filePath=${encodeURIComponent(filePath)}
`,
})
}
複制代碼
這(zhè)裏有幾個(gè)點需要(yào / yāo)注意一下
- 因爲(wéi / wèi)項目是(shì)通過 Taro 編譯出(chū)的(de),所以(yǐ)需要(yào / yāo) process.env.TARO_ENV 判斷代碼類型
- 調用 wx sdk 的(de) wx.miniProgram.navigateTo api 可以(yǐ)直接調用。不(bù)需要(yào / yāo)在(zài)微信公衆平台綁定域名權限驗證等。
- 跳轉路徑一定要(yào / yāo)寫完整 (因爲(wéi / wèi)少了(le/liǎo)一個(gè) / 一直無法跳轉,一度懷疑這(zhè)個(gè)思路行不(bù)通)
- 文件路徑一定要(yào / yāo)使用
encodeURIComponent
方法轉義。如果 filePath 路徑中包含一些參數,不(bù)轉義的(de)情況下路由跳轉的(de)過程中會丢失 - tokenId 用于(yú)權限鑒别(根據實際情況傳遞)
- 小程序原生頁面的(de)處理
const { filePath, fileExt, tokenId, fileName } = this.queryParams
const supports = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf']
// 支持預覽
if (supports.includes(fileExt)) {
const downloadResponse: any = await toPromise(wx.downloadFile, {
url: filePath,
header: {
'cookie': `tokenId=${tokenId};`,
}
})
const { tempFilePath } = downloadResponse
const openResponse = await toPromise(wx.openDocument, {
filePath: tempFilePath,
fileType: fileExt
})
} else {
// 該文件類型不(bù)支持預覽,下載
const filePath = wx.env.USER_DATA_PATH + `/${fileName}`
const saveResponse = await toPromise(wx.getFileSystemManager().saveFile, {
filePath,
tempFilePath,
})
}
複制代碼
這(zhè)裏有幾個(gè)點需要(yào / yāo)注意一下
-
對于(yú)有權限鑒定的(de)文件一般是(shì)通過 cookie 實現的(de),小程序中需要(yào / yāo)手動設置
wx.downloadFile
的(de) header 設置 cookie -
小程序中 api 的(de)回調方式很容易造成回調地(dì / de)獄,可以(yǐ)包裝一下 promise
-
将文件保存在(zài)本地(dì / de)這(zhè)個(gè)功能
wx.getFileSystemManager().saveFile
非常的(de)不(bù)人(rén)性化。下載後很難找到(dào)下載的(de)文件的(de)具體地(dì / de)址。暫時(shí)沒有找到(dào)好的(de)解決方案。
作者:不(bù)會撩妹的(de)楚留香
來(lái)源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出(chū)處。