最近做的專案需要在微信中二次分享,但是這個過程中遇到不少坑,所以記錄一下。至於為什麼坑多?主要是平時比較粗心,文件看的不夠仔細,其實文件已經說的很詳細了,我遇到好多的問題都是再仔細看看文件解決的;下面我就按照我的開發順序寫一寫,順便填一下坑;
準備,配置
首先要申請一個公眾號,而且要是企業公眾號!為什麼?因為普通賬號不支援分享!!!憑啥?!
第一步:準備
進入自己的公眾號,位置:開發>基本配置;在這裡拿到AppID和AppSecret,這兩個就是要在後面獲取token的api的引數;需要注意平臺不會儲存AppSecret,也不要把AppSecret放到前端暴露出來,我們放到node裡;
IP白名單也順便配置一下,就是呼叫獲取access_token介面時,需要設定訪問來源IP為白名單。也就是我們用的node伺服器ip;需要注意下的ip別獲取成內網的ip!,如果不知道百度搜尋ip就能查到了;
然後繼續再 公眾號設定>功能設定;配置js介面安全域名,這裡介紹也很詳細配置好域名,就可以呼叫js了,還有微信提供的簽名檔案要放到配置的域名下。
到這裡準備工作完成,剩下的就是擼程式碼了但這裡有個要注意,簽名檔案放置的路徑要和配置域名路徑一樣。
第二步:程式碼
node程式碼
我們專案加了一層node(用的是thinkjs框架),所以生成簽名(signature)就直接自己搞定;先來幾行程式碼看一下生成簽名的順序。 這裡主要看一下過程,所以沒有列出具體的程式碼實現,只摘了一部分拼湊一下
// 隨機數
const noncestr = Math.random().toString(36).substr(2);
// 時間戳
const timestamp = parseInt(new Date().getTime() / 1000);
// url
const url = this.ctx.param('url');
// 微信請求地址
const wx = {
'appId': 'xxxxxxxxx',
'appSecret': 'xxxxxxxxxx',
'tokenUrl': `https://api.weixin.qq.com/cgi-bin/token`,
'ticketUrl': `https://api.weixin.qq.com/cgi-bin/ticket/getticket`
}
// 獲取並儲存token
const accessToken = await this.getDataFromCache(
ACCESS_TOKEN_KEY,
this.getAccessToken(wx)
);
// 獲取並儲存ticket
const ticket = await this.getDataFromCache(
JS_TICKET_KEY,
this.getJsTicket(wx, accessToken)
);
// 生成
const signature = generateWXSign({
'jsapi_ticket': ticket,
'noncestr': noncestr,
'timestamp': timestamp,
'url': url
});
return { noncestr, timestamp, signature, wx.appId }
複製程式碼
首先我們要拿到token,通過token再獲取ticket,有了ticket就可以根據騰訊的演算法得到signature了!下面來段根據騰訊提供的演算法申請簽名的程式碼;還有不知道url有什麼亂七八糟的字元,所以decodeURIComponent是必須的
token,ticket 這來貨 都有時效 2小時,操作不好就bug
再附上兩個連結,官方的除錯工具:
- 驗證appid和appsecret url: mp.weixin.qq.com/debug?token…
- 驗證signature是否正確 url: mp.weixin.qq.com/debug/cgi-b…
import CryptoJS from 'crypto-js';
const genParamsStr = params => {
const keys = Object.keys(params);
return keys
.sort()
.reduce((ret, key) => {
if ( params[key]) {
ret.push(key + '=' + decodeURIComponent(params[key]));
return ret;
}
return '';
}, [])
.join('&');
};
module.exports = {
generateWXSign(panam) {
let signParam = genParamsStr(panam);
return CryptoJS.SHA1(signParam).toString();
}
};
複製程式碼
最開始的noncestr隨機數,timestamp時間戳,url,這三個值在前端程式碼中,微信配置部分也是需要的,所以生成signature後要一起返回;
到這兒node部分就結束了嗎?no!此處有一個坑會在下面‘填坑’部分講一下;
js部分
先把最基本的事幹了,擼一遍官方文件(mp.weixin.qq.com/wiki?t=reso… ),再引入騰訊的js,需要注意官網提供的最新版本,然後支援一下http,https;
<script src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
複製程式碼
現在我們再拿出《微信JS-SDK說明文件》如下,竟然有4個填空題!但我不怕,上面的node已經返回了,取到直接填上就好了; 有個要注意debug這個引數不管對錯,設定true都alert;
wx.config({
debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
appId: '', // 必填,公眾號的唯一標識
timestamp: '', // 必填,生成簽名的時間戳
nonceStr: '', // 必填,生成簽名的隨機串
signature: '',// 必填,簽名
jsApiList: [] // 必填,需要使用的JS介面列表
});
複製程式碼
附上一個圖
雖然要廢棄 onMenuShareAppMessage,onMenuShareTimeline但我還是繼續延用了,因為updateAppMessageShareData他們竟然。。。報錯,查了一下好像是版本問題,但已經是最新的js還是報錯。沒有再繼續排查問題,既然sdk說‘即將廢棄’那就是還沒廢棄,我就偷懶繼續用了;wx.ready(() => {
// 分享好友
wx.onMenuShareAppMessage({
title: share.product_title, // 分享標題
desc: share.product_description, // 分享描述
link: window.location.href, // 分享連結,該連結域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
imgUrl: share.product_image_url, // 分享圖示
success: function() {
console.log('onMenuShareAppMessage: success');
}
});
// 分享朋友圈
wx.onMenuShareTimeline({
title: share.product_title, // 分享標題
link: window.location.href, // 分享連結,該連結域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
imgUrl: share.product_image_url, // 分享圖示
success: function() {
// 使用者點選了分享後執行的回撥函式
}
});
});
複製程式碼
附上最後的程式碼,到這一步分享就已經完成了;後面說一下我遇到坑,或者是我自己犯的錯;
第三步 坑
下面列一下我遇到的問題,希望對看到這篇文章的人有所幫助
- 獲取token,ticket報的錯誤 'invalid ip 221.223.000.000, not in whitelist hint:[]'提示的很明顯了白名單沒配對,解決簡單貼上提示的ip到公眾號裡面的ip白名單就好了;
- 執行剛寫完程式碼也許有個 'invalid signature' 簽名錯誤,也很簡單驗證一下就好了,上面部分有附上官方測試工具;
- Error:invalid url domain ,這個錯誤就是公眾號中設定《JS介面安全域名》設定問題!先看提供的簽名txt檔案沒有放對位置,域名對不對別配著正式環境,再測試環境呼叫。
- 還有個事要注意,也是上面node部分沒有解釋的。線上的伺服器一般都是多臺(負載均衡),而最開始我們是把token,ticket快取在伺服器,這就導致了每次訪問其中一臺,剩下的伺服器存的token,tichet失效;ok,那就改了用redis;
- 到最後了,還不行嗎?那看看公眾號,開發>介面許可權 這個選單!!!
總結一下
主要仔細看文件!很多時候都是忽略了一些細節,導致坑了半天。
越不可思議的bug,越可能是弱X問題導致的!複製程式碼