微信分享

微信分享功能

該文章大部分取自官方文檔,加以自己的理解整理記錄。

因爲剛使用所以遇到很多不懂的地方,網上查了很多資料,大多數和官方文檔差不多,忽略了很多細節,這對剛剛接觸微信公衆號開發的我帶來不少麻煩,所以在這裏記錄一下自己的使用過程,遇到哪些問題,是怎麼解決的,希望對小白有用。

微信JS-SDK說明文檔

分享功能是在微信內置瀏覽器中才能使用的功能,暫不知道怎麼在PC上使用,如有知道,請不吝賜教。

本來使用JiaThis做PC端的微信分享的功能,但是後來分享業務被砍掉了,所以改爲微信公衆平臺做分享功能。

由於JS-SDK只能在微信內置瀏覽器使用,所以不能在PC上直接做分享功能,解決思路是在PC上生成一個二維碼地址,用微信掃一掃跳到這個地址,然後分享。

1. 綁定域名

只有綁定成功的域名才能調用對應微信公衆號接口。

先登錄微信公衆平臺進入“公衆號設置”的“功能設置”裏填寫“JS接口安全域名”。

這裏寫圖片描述
這裏寫圖片描述

這裏有兩點須有注意,在綁定域名的時候需要將指定的.txt文件下載後放到填寫域名或路徑指向的web服務器(或虛擬主機)的目錄。

1.1 域名的填寫

例如想綁定的域名爲http://wxainn.com,那麼輸入框裏填寫http://後面的部分,wxainn.com

1.2 指定.txt文件的放置

假如.txt的文件名爲wx.txt

無論服務器怎樣配置,只要在瀏覽器裏輸入http://wxainn.com/wx.txt能夠訪問到就可以,否則點擊保存的時候會提示以下信息。
這裏寫圖片描述

因爲我的服務器80端口已經用部署了應用程序,所以只需要將wx.txt放到/webapps/ROOT目錄下。當瀏覽器輸入http://wxainn.com/wx.txt時能夠訪問到該文件。

2. 引入JS文件

在需要調用JS接口的頁面引入如下JS文件,(支持https):

http://res.wx.qq.com/open/js/jweixin-1.2.0.js

比如這樣:

<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript"></script>

3. 通過config接口注入權限驗證配置

wx.config({
    debug: true, // 開啓調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時纔會打印。
    appId: '', // 必填,公衆號的唯一標識
    timestamp: , // 必填,生成簽名的時間戳
    nonceStr: '', // 必填,生成簽名的隨機串
    signature: '',// 必填,簽名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

我這裏使用Java作爲後臺開發語言,將這些參數寫在application.properties文件裏,在後臺計算好需要參數返回給前臺使用。

3.1 四個重要參數講解

下面說一下每個參數怎麼計算得出:

3.1.1 appId:公衆號的唯一標識,直接讀取配置文件。

這裏寫圖片描述

3.1.2 timestamp:當前時間戳(單位:秒)。

計算很簡單:

public static String getTimeStamp() {
    return String.valueOf(System.currentTimeMillis() / 1000);
}

3.1.2 nonceStr:生成簽名的隨機串

public static String getNonceStr() {
    Random random = new Random();
    return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "UTF-8");
}

3.1.4 signature:簽名

這4個參數,簽名計算最麻煩。簽名就是根據包括appIdtimestampnonceStr和其它一些參數計算得出的。所以這裏計算簽名所用到的參數,和傳到前臺的必須一一對應,否則前臺驗證不通過。下面說一下怎麼計算簽名。

3.1.4.1 獲取access_token

官方文檔說的很詳細,點擊標題可以查看。

access_token是公衆號的全局唯一接口調用憑據,公衆號調用各接口時都需使用access_tokenaccess_token的有效期目前爲2個小時,需定時刷新,重複獲取將導致上次獲取的access_token失效。

接口調用請求說明:

https請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

appid:第三方用戶唯一憑證,即上文的appid
secret:第三方用戶唯一憑證密鑰,即appsecret
這裏寫圖片描述

簡單描述獲取流程:

  1. 獲取自己的appidsecret
  2. 後臺定時任務,每隔一個小時獲取一次access_token
  3. 拼接請求url,get方式請求,將返回json值解析出access_token,存在Redis中。
3.1.4.2 jsapi_ticket

生成簽名之前必須先了解一下jsapi_ticketjsapi_ticket是公衆號用於調用微信JS接口的臨時票據。正常情況下,jsapi_ticket的有效期爲7200秒,通過access_token來獲取。由於獲取jsapi_ticket的api調用次數非常有限,頻繁刷新jsapi_ticket會導致api調用受限,影響自身業務,開發者必須在自己的服務全局緩存jsapi_ticket

接口調用請求說明:

https請求方式: GET
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

只有一個參數ACCESS_TOKEN,就是上一步獲取到的access_token

簡單描述獲取流程:

  1. 和獲取access_token寫在一個定時任務中,獲取完access_token緊接着獲取jsapi_ticket
  2. 拼接請求url,get方式請求,將返回json值解析出ticket,存在Redis中。

獲得jsapi_ticket之後,就可以生成JS-SDK權限驗證的簽名了。

3.1.4.3 計算signature

簽名生成規則如下:參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網頁的URL,不包含#及其後面部分) 。對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這裏需要注意的是所有參數名均爲小寫字符。對string1作sha1加密,字段名和字段值都採用原始值,不進行URL 轉義。

文檔說了一大堆,其實就簡單拼接一個字符串作sha1加密就可以,字符串格式如下:

jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL

參數順序不能變。
爲了便於區分參數和值,參數小寫,值大寫。

  • jsapi_ticket:前面獲取的jsapi_ticket
  • noncestr:前面提到的隨機串。
  • timestamp:前面提到的時間戳。
  • url:當前網頁的URL,不包含#及其後面部分。

這裏要注意url,不包含#及其後面部分並且不能對url進行轉義。格式如下:

http://mp.weixin.qq.com?params=value

拼接好字符串string1進行sha1加密即可,加密後得到的字符串就是簽名signature。

這裏我們服務器後臺計算簽名後傳到前臺頁面,微信會根據參數noncestrtimestamp和當前url,公衆號裏的appidappsecret再次進行計算簽名,如果兩次不一致,則不允許調用接口。

調試的時候可以用下面的小工具,檢查自己計算的簽名是否正確:

微信 JS 接口簽名校驗工具:
這裏寫圖片描述

4. 通過ready接口處理成功驗證

config信息驗證後會執行ready方法,所有接口調用都必須在config接口獲得結果之後,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對於用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。

wx.ready(function(){
    // 
});

5. 通過error接口處理失敗驗證

config信息驗證失敗會執行error函數,如簽名過期導致驗證失敗,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數中查看,對於SPA可以在這裏更新簽名。

wx.error(function(res){
    // 
});

6. 獲取“分享給朋友”按鈕點擊狀態及自定義分享內容接口(即將廢棄)

wx.onMenuShareAppMessage({
    title: '', // 分享標題
    desc: '', // 分享描述
    link: '', // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公衆號JS安全域名一致
    imgUrl: '', // 分享圖標
    type: '', // 分享類型,music、video或link,不填默認爲link
    dataUrl: '', // 如果type是music或video,則要提供數據鏈接,默認爲空
    success: function () {
    // 用戶點擊了分享後執行的回調函數
    }
});

7. 前臺頁面

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ include file="../../common/taglib.jsp" %>
<html>
<head>
    <meta charset="UTF-8">
    <title>邀請註冊-超級人才</title>
    <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">

    <meta name="theme-color" content="#4e8ef7">

    <!-- add to homescreen for ios -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
</head>
<body style="padding: 0;margin: 0; min-width: 300px; min-height: 500px">


<iframe src="${webUrl}" style="border: 0; margin: 0;padding: 0; height: 100%;width: 100%"></iframe>

<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript"></script>
<script>

    // alert("點擊分享,發送給朋友");

    wx.config({
        debug: false, // 開啓調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時纔會打印。
        appId: '${appId}', // 必填,公衆號的唯一標識
        timestamp: '${timestamp}', // 必填,生成簽名的時間戳
        nonceStr: '${nonceStr}', // 必填,生成簽名的隨機串
        signature: '${signature}',// 必填,簽名
        jsApiList: ['onMenuShareAppMessage', 'hideMenuItems'] // 必填,需要使用的JS接口列表
    });
    wx.ready(function () {
        // config信息驗證後會執行ready方法,所有接口調用都必須在config接口獲得結果之後,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對於用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。
        wx.hideMenuItems({
            menuList: [
                'menuItem:share:timeline',//分享到朋友圈: "menuItem:share:timeline"
                'menuItem:share:qq',//分享到QQ
                'menuItem:share:weiboApp',//分享到Weibo
                'menuItem:favorite',//收藏
                'menuItem:share:facebook',//分享到FB
                'menuItem:share:QZone'//分享到 QQ 空間
            ] // 要隱藏的菜單項,只能隱藏“傳播類”和“保護類”按鈕,所有menu項見附錄3
        });
        wx.onMenuShareAppMessage({
            title: '${welTitle}', // 分享標題
            desc: '${welSummary}', // 分享描述
            link: '${webUrl}', // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公衆號JS安全域名一致
            imgUrl: '${welPic}', // 分享圖標
            type: 'link', // 分享類型,music、video或link,不填默認爲link
            dataUrl: '', // 如果type是music或video,則要提供數據鏈接,默認爲空
            success: function () {
                // 用戶點擊了分享後執行的回調函數
                //關閉當前網頁
                wx.closeWindow();
            }
        });
    });
    wx.error(function(res){
        // config信息驗證失敗會執行error函數,如簽名過期導致驗證失敗,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數中查看,對於SPA可以在這裏更新簽名。
        alert(res)
    });
</script>
</body>
</html>

8. 成果

PC端頁面,點擊微信分享彈出二維碼:
這裏寫圖片描述

微信掃一掃後分享:
這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

9. 錯誤記錄

測試的時候遇到很多問題,現簡單列舉幾個,如果遇到類似問題,也許對你有幫助:

  1. 前臺驗籤失敗。原因是計算簽名用的timestampnoncestr和傳到前臺的不一致。
  2. 前臺驗籤失敗。原因是計算簽名的時候url路徑寫錯,沒有寫param=value部分,即?之後的部分。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章