最近產品部出了一個需求,要做一個分享的功能、在客戶端微信上面打開彈出一個h5的分享彈窗,點擊可以分享到微信朋友及朋友圈分享出去一張圖片,如下圖:
當時就想到,一般不都是微信中右上角有個三個點,點擊可以分享的嘛,幹嘛要還做這個多此一舉,於是跟產品部討論一番,說需點擊分享按鈕分享出去一張圖片,平時我們點擊右上角都是分享當前頁面的鏈接,滿足不了,徹底被產品部的需求震驚了,當時就想反手一巴掌,接下來就不用說了,遇到各種坑了,先來講講微信這個分享的步驟吧。
微信分享的步驟:
注意:一定要找個已經綁定好的微信公衆號 appId和secret、並且要引入微信的js
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
1、獲取訪問的token
String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret=a06e8ca9ea174a15b606d3db94e162e8";
2、通過token來獲取ticket
String accessTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
3、通過上面獲取的token和ticket來組裝一個url生成一個簽名signature
/**
* TODO - 獲取微信認證信息簽名信息
* @return
*/
@RequestMapping(value = "/get_wechat_authentication_info.htm")
@ResponseBody
public Map<String,Object> get_wechat_share_info(String accessToken,String ticket,String appId, String url) {
Map<String, Object> jsonMap = new HashMap<String, Object>();
/* * 產生隨機字符串 * */
String noncestr = UUID.randomUUID().toString().replaceAll( "\\-","").toUpperCase();
/* * 產生時間數值 * */
long timestamp = System.currentTimeMillis() / 1000;
/* * 產生字符串str和簽名signature * */
String str = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url;
String signature = SHA1(str);
jsonMap.put("timestamp",timestamp);
jsonMap.put("accessToken",accessToken);
jsonMap.put("ticket",ticket);
jsonMap.put("nonceStr",noncestr);
jsonMap.put("signature",signature);
jsonMap.put("appId",appId);
return jsonMap;
}
接下來是js中調用微信的一些函數來做分享處理、微信朋友及朋友圈的兩個監聽函數分別是:
wx.ready(function () {
// 監聽“分享給朋友”,按鈕點擊、自定義分享內容及分享結果接口
wx.onMenuShareAppMessage(obj);
wx.error(function(res){
alert("errorMSG"+res);
})
})
wx.ready(function () {
// 監聽“分享給朋友”,按鈕點擊、自定義分享內容及分享結果接口
wx.onMenuShareTimeline(obj);
})
這個是我寫的微信分享函數直接調用就可以了,裏面已經封裝了一個obj對象,因爲分享出來的圖片都不一樣,所以直接封裝起來
/**
* 微信分享
* @param type 1:朋友、2:朋友圈
* @param title
* @param desc
* @param link
* @param imgUrl
*/
function shareWechat(type){
var obj = {
title: '兩步路2018年度十大遊記達人評選', // 分享標題
desc: '約靠譜隊友,上「戶外助手」', // 分享描述
//分享的鏈接域名貨路徑必須與當前頁面對應的公衆號JS安全域名一直,也就是說這個appId的公衆號裏面必須要綁定這個www.xx.com域名,不然會出現提示 config inval url問題
link: 'https://www.xx.com/community/index_travel_vote.htm',
link: picUrl, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公衆號JS安全域名一致
// 該鏈接是重定向鏈接,因爲需要獲取用戶code,但是該鏈接又無法直接寫微信獲取code的鏈接,
// 所以需要點擊後重新加載新的頁面,來實現重定向,重新打開獲取code的微信鏈接,實現獲取用戶信息的功能;
imgUrl: picUrl, // 分享圖標
fail: function (res) {
alert(JSON.stringify(res)+"---");
},
/*success: function (res) {
// 用戶確認分享後執行的回調函數
alert('success'+res);
},
cancel: function (res) {
alert('cancel'+res);
}*/
};
if(type==1){
wx.ready(function () {
// 監聽“分享給朋友”,按鈕點擊、自定義分享內容及分享結果接口
wx.onMenuShareAppMessage(obj);
wx.error(function(res){
alert("errorMSG"+res);
})
})
}else if(type == 2){
wx.ready(function () {
// 監聽“分享給朋友”,按鈕點擊、自定義分享內容及分享結果接口
wx.onMenuShareTimeline(obj);
})
}
}
這個是獲取微信認證的想過信息,列入token、ticket、簽名的一些ajax請求
//獲取微信token
function getWxAccessToken(url){
$.ajax({
type:'get',
url: basePath + "/get_wechat_token.htm",
dataType:'json',
success:function(data){
var url = location.href;
if (data.errcode == "0") {
$.ajax({
type:'post',
url: basePath+'/community/get_wechat_authentication_info.htm',
data:{accessToken:data.access_token,ticket:data.ticket,url:url,appId:data.appId},
success:function(data){
wx.config({
debug: true, // 開啓調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時纔會打印。
appId: data.appId,
timestamp: data.timestamp, // 必填,生成簽名的時間戳
nonceStr: data.nonceStr, // 必填,生成簽名的隨機串
signature: data.signature,// 必填,簽名
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
]// 必填,需要使用的JS接口列表
});
}
});
}
}
});
}
注:獲取微信認證信息必須在後臺代碼中請求,不能通過ajax來訪問的,
/**
* TODO - 獲取微信token
* @return
*/
@RequestMapping(value = "/get_wechat_token.htm")
@ResponseBody
public Map<String,Object> get_wechat_token(){
Map<String, Object> jsonMap = null;
// m - 構建請求url
String accessTokenUrl = null;
String appId = "wxf4089e0e20e0c844b";
try {
if(redisUtil.get("jsonMap")!=null){
jsonMap = JSON.parseObject(redisUtil.get("jsonMap").toString(),Map.class);
}else{
accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret=a06e8ca9ea174a15b606d3db94e162e8";
byte[] httpResult = HttpUtil.httpGet(accessTokenUrl, null);
String httpResultJson = null;
httpResultJson = new String(httpResult, "utf-8");
jsonMap = JSON.parseObject(httpResultJson, Map.class);
String access_token = jsonMap.get("access_token")+"";
String expires_in = jsonMap.get("expires_in")+"";
if(StringUtil.isNotBlank(access_token) && StringUtil.isNotBlank(expires_in)){
String accessTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
byte[] httpResult2 = HttpUtil.httpGet(accessTicketUrl, null);
httpResultJson = new String(httpResult2, "utf-8");
jsonMap.clear();
jsonMap = JSON.parseObject(httpResultJson, Map.class);
jsonMap.put("access_token",access_token);
jsonMap.put("appId",appId);
redisUtil.set("jsonMap",JSON.toJSONString(jsonMap),Long.valueOf(expires_in));
}
}
}catch (Exception e) {
logger.error("wechat配置文件異常", e);
return jsonMap;
}
return jsonMap;
}
簽名的方法:
上面代碼已經寫完了,最後發現,點擊分享彈出H5窗口分享微信居然不成功、再點擊右上角的那個彈出來的微信窗口點擊分享朋友居然成功了,做到這裏我吐血了,居然微信把監聽事件已經綁定到了自帶的三個右上角彈出來的窗口分享中,自己開發的H5彈出來的不支持,只能改變右上角的那個分享,所以到最後還是放棄了這個開發,好在產品部優化了分享這個功能,經過這次研究還是蠻有收穫的。
遇到的問題:
1.分享的鏈接Link 域名必須要綁定微信公衆號JS接口中
2.H5自己開發的頁面分享不支持監聽事件,只能使用微信自帶的彈窗
3.微信測試這個比較煩人,對環境比較苛刻,一定要綁定域名,切記!!!