作者:陳惠,叩丁狼教育高級講師。原創文章,轉載請注明出處。
微信JS-SDK是微信公眾平臺 面向網頁開發者提供的基于微信內的網頁開發工具包。
通過使用微信JS-SDK,網頁開發者可借助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優質的網頁體驗。
我們先來看一個生活中常見的例子:
如圖所示的一個抽獎活動,抽獎次數有限,若次數使用完便不能再次參與抽獎,但是用戶分享到朋友圈之后,可增加一次抽獎機會,這樣便達到了宣傳的效果。
那我們應該怎么去實現呢?
實際上思路比較簡單,就是監聽分享到朋友圈的事件,在分享成功之后給他增加1次抽獎機會,但是,分享到朋友圈是微信里的功能,所以得使用微信提供的JSSDK才能完成。
實現步驟
一:綁定域名
在公眾號管理頁面,設置JS接口安全域名,表示該域名下的所有頁面,都擁有使用JSSDK的權限。
二:頁面中引入JS文件
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
三:通過config接口注入權限驗證配置
所有需要使用JS-SDK的頁面必須先注入配置信息,否則將無法調用JSSDK的相關API。
在頁面中添加這段js代碼
wx.config({
debug: true
appId: 'wx59687be81dd3d388',
timestamp: 1234567890,
nonceStr: 'wolfcode',
signature: '5c138e08a9d173c40c4e6280b02d008535bd17d8',
jsApiList: ['onMenuShareTimeline']
});
參數介紹
debug:true為開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若是生產環境則設置為false
appId:必填,公眾號的唯一標識
timestamp:必填,時間戳
nonceStr:必填,隨機生成的字符串
signature:必填,根據timestamp與nonceStr與jsapi_ticket按照某種算法生成的簽名
jsApiList:必填,需要使用的JS接口權限,如:使用分享朋友圈接口,則填入onMenuShareTimeline,其他接口的名稱可以在開發文檔中找到。
jsapi_ticket:
生成簽名signature還需要一個叫jsapi_ticket的參數,jsapi_ticket是公眾號用于調用微信JS接口的臨時票據,可以通過基礎接口的access_token來獲取,有效期為7200秒,調用次數有限,所以在后臺也需要全局緩存jsapi_ticket。
獲取jsapi_ticket的接口:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
代碼:
//獲取JSSDK的接口地址
public static final String GET_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
/**
* 獲取JSSDK的jsapi_ticket
*/
public static void getJsapi_ticket(){
//發起請求到指定的接口
String result = HttpUtil.get(GET_TICKET_URL.replace("ACCESS_TOKEN",getAccessToken()));
System.out.println(result);
}
getAccessToken是之前開發教程(四)已經實現好的,有需要的可參考http://www.lxweimin.com/p/85573685f17d
成功即返回如下JSON:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHFKA",
"expires_in":7200
}
獲得jsapi_ticket之后,就可以生成JS-SDK權限驗證的簽名了。
簽名算法:
規則如下:參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網頁的URL,不包含#及其后面部分) 。對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這里需要注意的是所有參數名均為小寫字符。最后對string1作sha1加密,字段名和字段值都采用原始值,不進行URL 轉義。
注意事項:
1.簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
2.簽名用的url必須是調用JS接口頁面的完整URL。
3.出于安全考慮,開發者必須在服務器端實現簽名的邏輯。
驗證簽名算法是否正確,可以打開https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
利用該工具,可以馬上獲取到簽名的結果,接下來我們把簽名拷貝到config中。
使用web開發者工具,打開我們的抽獎頁面,可以看到ok的提示,代表權限注入成功。
此時查看權限列表,該頁面已經擁有onMenuShareTimeline分享朋友圈的接口操作權限。
四:通過ready接口處理成功驗證
config權限驗證成功后會執行ready方法,相反失敗會執行error方法,所有接口調用都必須在config接口獲得結果之后,因為config是一個異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對于用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。
在ready中設置分享朋友圈相關功能
wx.ready(function(){
//分享到朋友圈接口
wx.onMenuShareTimeline({
title: '抽獎活動', // 分享時的標題
link: 'http://huihui.mynatapp.cc/gift.html', // 分享時的鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
imgUrl: 'http://www.wolfcode.cn/img/wolfcode/logo.png', // 分享時顯示的圖標
//用戶確認分享后執行的回調函數
success: function () {
//給用戶添加1次抽獎機會
playnum = 1;
$('.playnum').html(playnum);
},
//用戶取消分享后執行的回調函數
cancel: function () {
alert("取消分享");
}
});
});
效果:
注意:
我們應該在服務器端來實現簽名的邏輯,再把相關的參數值響應給頁面,前面主要是為了便于理解暫時直接用簽名工具生成好拷貝進去的。
在后臺計算簽名時算法參考:
/**
* 計算jssdk-config的簽名
* @param jsapi_ticket
* @param timestamp
* @param noncestr
* @param url
* @return
*/
public static String getSignature(String jsapi_ticket,Long timestamp,String noncestr,String url ){
//對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)
Map<String,Object> map = new TreeMap<>();
map.put("jsapi_ticket",jsapi_ticket);
map.put("timestamp",timestamp);
map.put("noncestr",noncestr);
map.put("url",url);
//使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1
StringBuilder sb = new StringBuilder();
Set<String> set = map.keySet();
for (String key : set) {
sb.append(key+"="+map.get(key)).append("&");
}
//去掉最后一個&符號
String temp = sb.substring(0,sb.length()-1);
//使用sha1加密
String signature = SecurityUtil.SHA1(temp);
return signature;
}