微信JSSDK遇見的坑--vue微信自定義分享

weixin_34402408發表於2019-02-23

其實無論是不是Vue版都是這些坑,記錄一下配置config與自定義分享踩坑記錄

網上找了一下,製作一個300300的圖示, 然後在模版里加入程式碼 <img src="300300的圖示" width="0" height="0" /> 這樣做了發現還是沒有縮圖。
微信6.5.5版本以後調整了分享規則,針對的是沒有接入公眾號的網頁分享,必須接入微信認證公眾號!
看詳情

所以想用圖片方式,或WeixinJSBridge(微信內建JSAPI)等方式均不可能,已經明確必須使用JSSDK,那就使用Js-sdk吧。

vue安裝Js-sdk

npm install weixin-js-sdk mint-ui --save

然後新建一個wechat.js檔案,src目錄下任意地方
注意這裡有訪問api獲取簽名資料,建議除錯時最好把 wx.config的debug設為true

//weixin-js-sdk應用
const wx = require('weixin-js-sdk')  //如果引入失敗,vue頁面會報致命錯誤,沒報說明引入成功
export default {
  methods: {
    wechatShare(info) {
      // 判斷蘋果手機
      let _url = ''
      if (window.__wxjs_is_wkwebview === true) {
        _url = window.location.href.split('#')[0] || window.location.href
      } else {
        _url = window.location.href
      }
      // 訪問後臺介面獲取微信引數
      this.$store
        .dispatch('GetWxParam', { url: encodeURIComponent(_url) })
        .then(res => {
          wx.config({
            debug: false,
            appId: res.data.appId, // 必填,公眾號的唯一標識
            timestamp: res.data.timestamp, // 必填,生成簽名的時間戳
            nonceStr: res.data.nonceStr, // 必填,生成簽名的隨機串
            signature: res.data.signature, // 必填,簽名,見附錄1
            jsApiList: [
              'previewImage',
              'hideAllNonBaseMenuItem',
              'showMenuItems',
              'onMenuShareTimeline',
              'onMenuShareAppMessage',
              'chooseWXPay'
            ] // 必填,需要使用的 JS 介面列表,所有JS介面列表見附錄2
          })
        })
        .catch(err => {
          console.log(err)
        })
      wx.ready(() => {
        const share_title = info.title
        const share_desc = info.desc
        const share_link = info.link
        const share_img = info.img
        wx.showOptionMenu()
        wx.onMenuShareTimeline({
          title: share_title, // 分享標題
          link: share_link, // 分享連結
          imgUrl: share_img, // 分享圖示
          success: function() {
            alert('已成功分享1')
          }
        })
        wx.onMenuShareAppMessage({
          title: share_title, // 分享標題
          desc: share_desc, // 分享描述
          link: share_link, // 分享連結
          imgUrl: share_img, // 分享圖示
          success: function() {
            alert('已成功分享2')
          }
        })
      })
    }
  }
}
import wxShare from "../wechat";   //自己找對路徑
export default {
mixins: [wxShare], 
methods: {
 setShare() {
   const shareInfo = {
        title: `自定義標題`,
        desc: `自定義描述`,
        link: "http://www.phps.shop/#/",
        img: "https://www.phps.shop/wx.png"
    } 
    this.wechatShare(shareInfo)
  },
},
created(){ 
    this.setShare()
}
}

wx.config的debug設為true的話開啟頁面會顯示簽名是否成功,若顯示 invalid signature,不要去糾結其他問題了,就是簽名錯誤。
不是通過頁面工具進行校驗,簽名就一定正確的,因為簽名和當前url是關聯的,當前url多個字元都會報簽名錯誤

invalid signature 很明顯簽名錯誤

解決辦法
1、確認簽名演算法是否正確,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 頁面工具進行校驗。
2、確認config中noncestr, timestamp與用以簽名中的對應noncestr, timestamp一致。
3、確認 config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。
4、確認url是頁面完整的url,包括GET引數部分。

確定123都沒問題,那基本就是4的問題。比如你生成簽名是url是http://www.phps.shop
但訪問的頁面是http://www.phps.shop?id=1或者http://www.phps.shop/#,都會提示簽名錯誤,注意vue的/#

另記錄一下api端獲取簽名的記錄

下面沒有做對應的儲存,只是log記錄了下

//獲取公眾號的access_token,注意這裡不是使用者的access_token
    public function access_token(){
        $url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
        $surl=sprintf($url,$this->gzhAppID,$this->gzhAppSecret);
        $access = curl_get($surl);
        $access = json_decode($access,true);
        $access_token = $access['access_token'];
        Log::error('access_token:'.$access_token);
        $this->get_ticket($access_token);
        return  $access_token;
    }
//獲取ticket
    public function get_ticket($access_token)
    {
        $url='https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi';
        $json = curl_get($url);
        $arr = json_decode($json,true);
        $ticket = $arr['ticket'];
        Log::error('ticket:'.$ticket);
        $this->get_sign($ticket);
        return  $ticket;
    }
//獲取簽名
    public function get_sign($ticket){
        $time=time();
        $jsapi_ticket = $ticket;
        $noncestr='Wmt8dfcjPz0z';
        $timestamp=$time;
        $url='http://m.phps.shop/#/';
        $str="jsapi_ticket=%s&noncestr=%s&timestamp=%s&url=%s";
        $sign = sprintf($str,$jsapi_ticket,$noncestr,$timestamp, $url);
        $sign = sha1($sign);
        Log::error('sign:'.$sign);
        Log::error('time:'.$time);
        return $sign;
    }

相關文章