微信小程序分享到朋友圈之曲線救國

遇到的問題

通過屢次重大更新,微信始終沒有開放小程序直接分享到朋友圈的相關api。javascript

曲線救國

咱們直接開門見山,用間接的方式來實現微信小程序分享到朋友圈
這裏先來羅列一下實現思路html

  1. 經過微信api申請小程序二維碼
    獲取小程序二維碼接口文檔
  2. 下載二維碼到服務器並返回url
  3. 小程序接收url並從服務器下載圖片
    wx.downloadFile
  4. 小程序將下載好的圖片保存至用戶相冊
    wx.saveImageToPhotosAlbum

實現過程

首先經過閱讀獲取小程序二維碼接口文檔獲取申請小程序二維碼的接口
這裏我使用的是不限次的二維碼接口即B方案
代碼示例:java

wx.request({
  method: 'POST',
  url: app.apiUrl + '/miniprogram/qrcode',
  data: {
    appid: app.appid,
    page: 'pages/activityInfo/activityInfo',
    scene: 'id:' + this.data.activity.id
  },
  header: {
    'content-type': 'application/x-www-form-urlencoded',
    'X-TOKEN': app.jwt
  },
  success(res) {
    res = res.data // 這裏我是從服務器直接返回保存好的圖片url
    ... // 後文介紹保存過程
  },
  fail() {
    wx.hideLoading()
    app.$alert('分享失敗', 'wrong', _this)
  }
})

發送請求前咱們須要準備好頁面的page(開頭不能帶有「/」)路徑及scene(頁面參數)
文檔中對scene字段只有簡單的描述並無給到實際示例,這裏其實很容易誤導新人,不知道這個scene具體應該如何使用。golang

最大32個可見字符,只支持數字,大小寫英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符請自行編碼爲合法字符(因不支持%,中文沒法使用 urlencode 處理,請使用其餘編碼方式)

以上是官方對scene的介紹
其實這裏就是一個單純的字符串,至於參數如何傳遞咱們徹底能夠自行設計,本身喜歡就好。必定要注意官方有限制使用的特殊字符(!#$&'()*+,/:;=?@-._~)
這裏我使用的是 key:value;key:value形式,當用戶掃碼後經過onLoad(options)來獲取sceneweb

onLoad (options) {
    // 由於這裏要跟正常url傳參作區分,因此要先判斷scene是否存在
    if (options.scene) {
      let scene = decodeURIComponent(options.scene) // 官方要求必定要先decodeURIComponent才能正常使用scene
      scene = scene.split(';')
      let obj = {}
      for (let i = 0; i < scene.length; i++) {
        let item = scene[i].split(':')
        obj[item[0]] = item[1]
      }
      // 將options.id 替換爲scene中提取的id 以保證後續業務不受影響
      options.id = obj.id
    }
}

服務端實現

服務端我用的是golang
沒有什麼緣由,就由於該項目的後端是golang搭建的,本身也在練習golang,因此服務端代碼寫的沒有任何水平,還請路過的大神指點一二,這裏主要介紹實現思路json

func GetMiniProgramQrcode(c *gin.Context) {
    // 獲取應用的appid
    appid := c.PostForm("appid")
    // 後端獲取小程序傳來的page及scene
    page := c.PostForm("page")
    scene := c.PostForm("scene")
    
    // 考慮到反覆請求微信接口的耗時及服務器io消耗,我打算把圖片經過MD5(page+scene)的方式命名
    h := md5.New()
    h.Write([]byte(page + scene)) // 須要加密的字符串
    cipherStr := h.Sum(nil)
    result := hex.EncodeToString(cipherStr)
    exist, _ := model.PathExists("服務器文件存儲路徑" + result + ".jpg") // 檢測圖片是否已經存在(即以前是否有人分享過相同頁面)
    if exist {
        // 若二維碼文件存在直接返回路徑
        c.String(200, "URL訪問路徑"+result+".jpg")
    } else {
        // 不存在則直接請求微信獲取二維碼
        token, ok := GetAccessToken(appid) // 首先獲取access_token 這裏你們根據本身的業務方式來獲取
        if !ok {
            c.JSON(200, gin.H{
                "code": 4001,
                "msg":  "accesstoken 獲取失敗",
            })
        } else {
            // 向微信請求小程序二維碼圖片
            // 這裏須要注意!!! 官方只介紹了經過該接口以post的形式傳參,但其實參數是要嚴格的json格式傳遞才能正常獲取
            resp, err := http.Post("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+token,
                "application/x-www-form-urlencoded",
                strings.NewReader(`{"page":"`+page+`", "scene":"`+scene+`"}`))
            if err != nil {
                fmt.Println(err)
            }

            defer resp.Body.Close()
            body, err := ioutil.ReadAll(resp.Body)
            if err != nil {
                // handle error
            }
            // 圖片寫入本地
            err = ioutil.WriteFile("服務器文件存儲路徑"+result+".jpg", body, 0755)
            if err != nil {
                fmt.Println(err)
                c.JSON(200, gin.H{
                    "code": 4002,
                    "msg":  "文件寫入服務器失敗",
                })
            }else{
                // 寫入成功 直接返回url
                c.String(200, "URL訪問路徑"+result+".jpg")
            }
        }
    }
}

經過上述邏輯咱們能夠正常獲取到圖片url地址
接下來就是將圖片下載到小程序本地並保存到用戶相冊中小程序

// 接着第一塊代碼片中省略部分 咱們已經獲取到服務器返回的二維碼圖片url(res)
wx.downloadFile({ // 調用wx.downloadFile接口將圖片下載到小程序本地
  url: app.webUrl + res,
  success(res) { // 下載成功後會生成一個臨時文件路徑 res.tempFilePath(這時res變量已經被新的回調替換了哦,已經不是服務器返回來的res了)
    wx.saveImageToPhotosAlbum({ // 接着調用wx.saveImageToPhotosAlbum將圖片保存到用戶手機相冊,該接口須要用戶受權纔可使用,在調用過程當中微信會自動彈框請求受權,若是用戶拒絕則直接調用fail回調,且一段時間內不會從新請求,這裏你們能夠經過微信權限設置接口從新引導用戶受權
      filePath: res.tempFilePath,
      success(res) {
        wx.hideLoading()
        wx.showModal({ // 保存成功後記得提醒用戶二維碼已經存到他的手機相冊了哦
          title: '分享二維碼已保存到系統相冊',
          content: '快去分享給朋友,讓更多的朋友發現這裏的美好',
          success: function (res) {
            if (res.confirm) {
              console.log('用戶點擊肯定')
            } else if (res.cancel) {
              console.log('用戶點擊取消')
            }
            _this.shareCancle()
          }
        })
      },
      fail(res) {
        wx.hideLoading()
        app.$alert('分享失敗', 'wrong', _this)
      }
    })
  },
  fail: function (res) {
    wx.hideLoading()
    app.$alert('分享失敗', 'wrong', _this)
  }
})

如此就完成了微信小程序分享到朋友圈的功能,感受也是有點艱辛啊。後端

掃碼體驗

圖片描述

相關文章
相關標籤/搜索