實(shí)現(xiàn)微信小程序內(nèi)嵌H5中的下載功能

項(xiàng)目場(chǎng)景如下

開(kāi)發(fā)框架是uniapp镊绪,使用uniapp腳手架搭建,最終打包成H5部署在服務(wù)器上。
微信小程序的主體內(nèi)容使用了<web-view>標(biāo)簽將H5的頁(yè)面內(nèi)容展示,H5中有頁(yè)面存放了下載的路徑泉粉。點(diǎn)擊下載按鈕下載文件,或者預(yù)覽文件讓用戶手動(dòng)保存榴芳。

難點(diǎn)

如果是pc端嗡靡,下載用一個(gè)<a>標(biāo)簽就很容易,但是在小程序里的<web-view>標(biāo)簽中是行不通的窟感。此外讨彼,小程序里的<web-view>與小程序的通行方式主要用postMessage,但是觸發(fā)條件非呈疗恚苛刻,參照微信的官方文檔哈误,只在小程序后退,組件銷毀躏嚎,還有分享時(shí)才會(huì)觸發(fā)postMessage并一次性把值全部帶出來(lái)蜜自,使用起來(lái)非常不變,對(duì)于小程序?qū)嶋H內(nèi)容主體是<web-view>內(nèi)嵌的spa的H5頁(yè)面的情況下卢佣,銷毀組件會(huì)帶來(lái)很多麻煩重荠,因此最后放棄了這個(gè)方案。

我的方法

首先必不可少的是安裝jweixin-module模塊

npm i jweixin-module

在main.js中將依賴綁定

import wx from  "jweixin-module"
Vue.prototype.$wx = wx 

H5對(duì)應(yīng)頁(yè)面點(diǎn)擊下載時(shí)
假設(shè)你的文件路徑是
https://sample.com/apiName.do?fileToken=ABCDEFG&fileName=HIJKLMN.png
這里有需要注意的3點(diǎn)
1是虚茶?會(huì)被微信小程序解析戈鲁,所以需要替換成&,等傳入微信再去拼接
2是fileName與fileToken嘹叫,假設(shè)鏈接里有這些額外的參數(shù)荞彼,那這些參數(shù)因?yàn)楹芸赡芙M成內(nèi)容比較復(fù)雜,會(huì)有特殊字符待笑,所以需要轉(zhuǎn)義鸣皂,然后在微信小程序的看情況有需要的話就解析回去。這里使用encodeURIComponent與decodeURIComponent去處理可能存在特殊字符的字段暮蹂。
3是我的實(shí)際場(chǎng)景里寞缝,獲取服務(wù)器的圖片需要鑒權(quán),所以我會(huì)額外帶一個(gè)cookie仰泻,也使用&拼接在鏈接后荆陆。

let fileToken = "ABCDEFG"
let fileName = "HIJKLMN.png"
this.$wx.miniProgram.navigateTo({
  url:"/pages/upload/page?link=https://sample.com/apiName.do&fileToken="+encodeURIComponent(fileToken) + "&fileName=" + encodeURIComponent(fileName)
})

小程序里,對(duì)應(yīng)的/pages/upload/page頁(yè)面

onLoad: function(options) {
    let that = this;
    wx.setStorageSync('uploadData', options)//保存?zhèn)魅氲膮?shù)
//option為一個(gè)對(duì)象集侯,內(nèi)容就是{ link,fileToken,fileName,cookie等之前使用&拼上的數(shù)據(jù)}
    let pages = getCurrentPages();
    let previousPage = pages[pages.length - 2]; //上一個(gè)頁(yè)面
    previousPage.setData({
      isDownLoadPageBack: true  //在上一個(gè)頁(yè)面設(shè)置標(biāo)記被啼,用來(lái)判斷
    })
    wx.navigateBack({
      delta: 1
    })
  },

返回到之前有web-view 的頁(yè)面

data: {
    isDownLoadPageBack: false,
  },
onShow: function() {
    wx.hideHomeButton();
    if (this.data.isDownLoadPageBack) {
      this.getDownLoadFile() //具體的微信下載文件的方法
    }
//每次onShow執(zhí)行完帜消,還有上面的下載方法執(zhí)行完后要把這個(gè)標(biāo)記重置為false,這樣不同情況觸發(fā)的onShow才能區(qū)分是否是下載文件頁(yè)面回來(lái)的浓体∨萃Γ可能寫(xiě)的重復(fù)但是多寫(xiě)幾次比較放心
    this.setData({
      isDownLoadPageBack: false
    })
  },

下載方法

getDownLoadFile: function() {
    wx.showLoading({
      title: '下載中', //提示文字
      mask: true, //是否顯示透明蒙層,防止觸摸穿透命浴,默認(rèn):false  
    })
    let that = this;
    let options = wx.getStorageSync('uploadData')
    let timeStamp = (Date.parse(new Date())) / 1000; //定義了時(shí)間戳拼接在文件名前防止名字重復(fù)
//這里是判斷文件類型娄猫,是否是圖片,后面用來(lái)判斷并使用不同的展示方式
//寫(xiě)的很菜生闲,湊合看下就行
    let originFileName = decodeURIComponent(options.fileName)
    let originFileNameSplit  = originFileName.split('.')
    let fileNameType = originFileNameSplit[originFileNameSplit.length - 1]
    let imageType = ['gif', 'png', 'jpg', 'tif', 'bmp', 'webp', 'jpeg', 'JPG', ]
    let myCookie = decodeURIComponent(options.cookie)
    const downloadTask = wx.downloadFile({ //微信下載文件方法
    //這里拼接成需要的格式
      url: options.link + '?fileToken=' + options.fileToken + '&&fileName=' + options.fileName,
      header: {
        'cookie': myCookie
      },
      success(res) {
        wx.getFileSystemManager().saveFile({ //微信保存文件媳溺,這個(gè)存儲(chǔ)有點(diǎn)復(fù)雜
          // 臨時(shí)存儲(chǔ)路徑,先有臨時(shí)存儲(chǔ)路徑方可使用wx官方的存儲(chǔ)本地路徑( wx.env.USER_DATA_PATH )
          tempFilePath: res.tempFilePath,
          //定義本地的存儲(chǔ)路徑及名稱
          filePath: wx.env.USER_DATA_PATH + '/' + timeStamp + originFileName,
          success(res) {
            const savedFilePath = res.savedFilePath;
            wx.hideLoading()
            if (imageType.includes(fileNameType)) {
              wx.previewImage({
                urls: [savedFilePath],
              })
            } else {
              wx.openDocument({ //微信打開(kāi)文件
                filePath: savedFilePath,
                showMenu: true,
                success: function(res) {
                  that.setData({
                    waitWord: '返回請(qǐng)點(diǎn)擊左上角',
                    isDownLoadPageBack: false
                  });
                },
                fail: function(err) {
                  console.log(res)
                  wx.showToast({
                    title: '預(yù)覽失敗',
                    icon: 'error',
                    duration: 1500
                  })
                  that.setData({
                    waitWord: '文件預(yù)覽失敗,請(qǐng)稍后重試',
                    isDownLoadPageBack: false
                  });
                }
              });
            }

          },
          fail(err) {
            wx.showToast({
              title: '預(yù)覽失敗',
              icon: 'error',
              duration: 1500
            })
            that.setData({
              waitWord: '文件預(yù)覽失敗,請(qǐng)稍后重試',
              isDownLoadPageBack: false
            });
          }
        })

      },
      fail(err) {
        wx.hideLoading()
        wx.showToast({
          title: '下載失敗',
          icon: 'error',
          duration: 1500
        })
        console.log(err)
        that.setData({
          waitWord: '文件下載失敗,請(qǐng)稍后重試',
          isDownLoadPageBack: false
        });
      }
    })
    downloadTask.onProgressUpdate((res) => {
      console.log('下載進(jìn)度', res.progress)
      console.log('已經(jīng)下載的數(shù)據(jù)長(zhǎng)度', res.totalBytesWritten)
      console.log('預(yù)期需要下載的數(shù)據(jù)總長(zhǎng)度', res.totalBytesExpectedToWrite)
    })
  }

總結(jié)

大致過(guò)程就這樣碍讯。缺點(diǎn)是點(diǎn)擊下載時(shí)頁(yè)面會(huì)一閃而過(guò)空白的微信頁(yè)面再回來(lái)悬蔽。如果有其他的更友好的實(shí)現(xiàn)方式也請(qǐng)不吝賜教。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捉兴,一起剝皮案震驚了整個(gè)濱河市蝎困,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌轴术,老刑警劉巖难衰,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钦无,死亡現(xiàn)場(chǎng)離奇詭異逗栽,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)失暂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門彼宠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人弟塞,你說(shuō)我怎么就攤上這事凭峡。” “怎么了决记?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵摧冀,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我系宫,道長(zhǎng)索昂,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任扩借,我火速辦了婚禮椒惨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘潮罪。我一直安慰自己康谆,他們只是感情好领斥,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著沃暗,像睡著了一般月洛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上描睦,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天膊存,我揣著相機(jī)與錄音,去河邊找鬼忱叭。 笑死隔崎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的韵丑。 我是一名探鬼主播爵卒,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼撵彻!你這毒婦竟也來(lái)了钓株?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤陌僵,失蹤者是張志新(化名)和其女友劉穎轴合,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體碗短,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡受葛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了偎谁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片总滩。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖巡雨,靈堂內(nèi)的尸體忽然破棺而出闰渔,到底是詐尸還是另有隱情,我是刑警寧澤铐望,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布冈涧,位于F島的核電站,受9級(jí)特大地震影響正蛙,放射性物質(zhì)發(fā)生泄漏督弓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一跟畅、第九天 我趴在偏房一處隱蔽的房頂上張望咽筋。 院中可真熱鬧,春花似錦徊件、人聲如沸奸攻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)睹耐。三九已至辐赞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間硝训,已是汗流浹背响委。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窖梁,地道東北人赘风。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像纵刘,于是被迫代替她去往敵國(guó)和親邀窃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容