前題
- 本篇適用范圍: 使用微信JS-SDK接口調(diào)用混卵,分享朋友圈、朋友窖张、QQ幕随、QQ空間、騰訊微博等宿接,包括分享鏈接中帶有參數(shù)赘淮。
- 說明:在Android和iOS端辕录,分享測試均已通過。
開發(fā)準備
- 已認證公眾號梢卸。登錄微信公眾號確認有相關(guān)功能使用權(quán)限走诞,參見下圖
- 設(shè)置JS接口安全域名。確保分享鏈接域名和設(shè)置的安全域名一致
微信公眾號中低剔,在【設(shè)置---公眾號設(shè)置---功能設(shè)置】速梗,設(shè)置JS接口安全域名,如圖
- 獲取AppID和AppSecret襟齿。在微信公眾號中獲取該信息并保存姻锁,后面簽名算法和config配置中會用到。
實現(xiàn)邏輯
后臺通過AppID和AppSecret請求微信接口獲取access-token參數(shù)猜欺,以此access-token參數(shù)再次請求微信接口獲取jsapi-ticket位隶,并將獲取的jsapi-ticket進行加密、校驗與其他的參數(shù)封裝成json格式的數(shù)據(jù)傳送到前臺JS頁面
前臺獲取json數(shù)據(jù)后开皿,并提供給參數(shù)給微信分享接口調(diào)用涧黄,具體接口為wx.config,wx.ready; 獲取微信分享頁面的標題和描述赋荆,以及分享地址笋妥、縮略圖地址
JS-SDK使用步驟--后臺
參考官方文檔 附錄1--JS-SDK使用權(quán)限簽名算法
- 獲取access-token
AccessToken需要用CorpID和Secret來換取,不同的Secret會返回不同的AccessToken窄潭。此處可使用前面獲取的AppID和AppSecret春宣,需使用Https協(xié)議、Json數(shù)據(jù)格式嫉你、UTF8編碼
請求示例:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=appId&corpsecret=appSecret
詳細內(nèi)容請參考官方文檔-獲取access-token
- 獲取jsapi-ticket
用第一步拿到的access_token 采用http GET方式請求獲得jsapi_ticket(有效期7200秒月帝,開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket)。
請求示例:https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN
- 獲取簽名(signature)
簽名生成規(guī)則如下:參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳),url(當(dāng)前網(wǎng)頁的URL幽污,不包含#及其后面部分嚷辅,即前端發(fā)起請求傳過來的URL參數(shù))。需要注意的是所有參數(shù)名均為小寫字符距误。對string1作sha1加密簸搞,字段名和字段值都采用原始值,不進行URL 轉(zhuǎn)義准潭。源代碼參考如下:后臺簽名源代碼下載
- 封裝json參數(shù)攘乒,返回給前端
將獲取的jsapi-ticket進行加密、校驗與其他的參數(shù)封裝成json格式的數(shù)據(jù)傳送到前臺JS頁面惋鹅,返回內(nèi)容可參考wx.config配置中所需內(nèi)容则酝。
建議
驗證簽名是否一致,可以使用微信的驗證簽名工具;建議使用微信web開發(fā)者工具調(diào)試JS-SDK
JS-SDK使用步驟--前端
- 引入JS文件
在需要調(diào)用JS接口的頁面引入如下JS文件沽讹,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
備注:支持使用 AMD/CMD 標準模塊加載方法加載
- 通過config接口注入權(quán)限驗證配置
wx.config({
debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來般卑,若要查看傳入的參數(shù),可以在pc端打開爽雄,參數(shù)信息會通過log打出蝠检,僅在pc端時才會打印。
appId: '', // 必填挚瘟,企業(yè)號的唯一標識叹谁,此處填寫企業(yè)號corpid
timestamp: , // 必填,生成簽名的時間戳
nonceStr: '', // 必填乘盖,生成簽名的隨機串
signature: '',// 必填焰檩,簽名,見附錄1
jsApiList: [] // 必填订框,需要使用的JS接口列表析苫,所有JS接口列表見附錄3
});
- 通過ready接口處理成功驗證
wx.ready(function(){
// config信息驗證后會執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后穿扳,config是一個客戶端的異步操作衩侥,所以如果需要在頁面加載時就調(diào)用相關(guān)接口,則須把相關(guān)接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行矛物。對于用戶觸發(fā)時才調(diào)用的接口茫死,則可以直接調(diào)用,不需要放在ready函數(shù)中履羞。
});
- 通過error接口處理失敗驗證
wx.error(function(res){
// config信息驗證失敗會執(zhí)行error函數(shù)峦萎,如簽名過期導(dǎo)致驗證失敗,具體錯誤信息可以打開config的debug模式查看吧雹,也可以在返回的res參數(shù)中查看,對于SPA可以在這里更新簽名涂身。
});
- 示例代碼(基于vue)
- 在調(diào)用頁面引入JS雄卷,例如index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--<meta name="viewport" content="width=device-width,initial-scale=1.0">-->
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
<title>Index</title>
<!-- 必須引入的文件-->
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
.....
</body>
</html>
- index.js
import Vue from 'vue'
import Router from 'vue-router'
import restoreUrl from '../utils/restoreUrl';
Vue.use(Router)
let router = new Router(yourRouter)
// 路由攔截
router.beforeEach((to, from, next) => {
// 微信分享時,微信會在地址欄添加額外參數(shù)
if (restoreUrl.isWeChatUrl()) {
window.location.href = restoreUrl.getProjectUrl();
}
})
export default router
- restoreUrl.js
多次分享蛤售,去除微信添加參數(shù)丁鹉,
export default {
// 判斷地址欄出現(xiàn)微信自己加的參數(shù)問題
isWeChatUrl () {
// debugger;
let url = window.location.href;
let matchResult = url.match(/\?/g);
// 如果地址欄中,出現(xiàn)了兩個問號的話悴能,那么是微信在分享添加了參數(shù)
// 如果地址欄中揣钦,出現(xiàn)了form=,那么就是微信分享添加的參數(shù)
return (matchResult ? matchResult.length >= 2 : false) || (/from=/.test(url));
},
// 把地址欄的中微信追加的參數(shù)去掉,返回我們自己項目的地址
getProjectUrl () {
let location = window.location;
return location.origin + location.pathname + location.hash;
}
};
- 進入分享頁面時調(diào)用onShare()
// 分享
onShare() {
// 傳入后臺簽名URL漠酿,域名+當(dāng)前分享頁面路徑
let _WXurl = window.location.origin + window.location.pathname;
// 定義分享鏈接,使用encodeURIComponent對傳入?yún)?shù)編碼冯凹,防止在iOS中傳入?yún)?shù)編碼問題
// 此處示例傳遞單個參數(shù)
let _shareLink = window.location.origin+ '/#?'+encodeURIComponent('key')+"="+ encodeURIComponent('value');
let params = {
url:_WXurl
};
//向后臺發(fā)起請求獲得config配置參數(shù)
this.$post('/v1/system/shareUrl', params,{
// 請求header中,Content-Type需為以下類型炒嘲,防止分享出去參數(shù)丟失
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
})
.then((res) => {
if (res.data.errCode === 0) {
// 請求接口成功后宇姚,
// 配置config
wx.config({
// 開啟調(diào)試模式時,調(diào)用的所有api的返回值會在客戶端alert出來匈庭,若要查看傳入的參數(shù),可以在pc端打開浑劳,參數(shù)信息會通過log打出阱持,僅在pc端時才會打印。
debug: false,
// 后臺返回之前獲取的appId
appId: res.data.body.appId,
// 必填魔熏,生成簽名的時間戳
timestamp: res.data.body.timestamp,
// 必填衷咽,生成簽名的隨機串
nonceStr: res.data.body.nonceStr,
// 必填,簽名蒜绽,見附錄1
signature: res.data.body.signature,
// 必填镶骗,需要使用的JS接口列表,所有JS接口列表見附錄3
jsApiList: ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'hideMenuItems' ]
});
// 微信檢查接口列表
wx.checkJsApi({
jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'hideMenuItems'], // 需要檢測的JS接口列表
success: function (res) {
console.log(res);
// alert('checkJsApi' + res);
}
});
// 隱藏微信右上角彈出菜單中部分功能按鈕
wx.hideMenuItems({
menuList: ['menuItem:share:qq','menuItem:share:QZone','menuItem:share:weiboApp','menuItem:copyUrl'], // 要隱藏的菜單項滓窍,只能隱藏“傳播類”和“保護類”按鈕卖词,所有menu項見附錄4
success: function (res) {
// alert(res);
}
});
// 頁面加載完成后用戶就有可能調(diào)用微信的分享,所以當(dāng)頁面ready 完后就加載
wx.ready(function () {
// alert(_shareLink);
// 分享到朋友圈
wx.onMenuShareTimeline({
// 分享標題
title: '你的夢想',
// 分享鏈接吏夯,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致
link: _shareLink,
// 分享圖標
imgUrl: 'https://www.baidu.com/images/1.png',
// 用戶確認分享后執(zhí)行的回調(diào)函數(shù)
success: function () {
console.log('分享回調(diào)函數(shù)');
console.log('shareLink= '+_shareLink);
// alert('分享回成功調(diào)函數(shù)');
},
// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
cancel: function () {
console.log('取消分享回調(diào)函數(shù)');
// alert('取消分享回調(diào)函數(shù)');
}
});
// 分享好友
wx.onMenuShareAppMessage({
// 分享標題
title: '接你的夢想',
// 分享描述
desc: '從來都不是夢',
// 分享鏈接此蜈,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致
link: _shareLink,
// 分享圖標
imgUrl: 'https://www.baidu.com/images/1.png',
// 用戶確認分享后執(zhí)行的回調(diào)函數(shù)
success: function () {
console.log('分享好友回調(diào)函數(shù)');
console.log('shareLink= '+_shareLink);
// alert('分享回好友調(diào)函數(shù)');
},
// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
cancel: function () {
console.log('取消分享好友調(diào)函數(shù)');
// alert('取消分享回調(diào)函數(shù)');
// console.log('分享回好友調(diào)函數(shù)');
}
});
// 分享多個地址時,可統(tǒng)一傳入?yún)?shù)噪生,如 wx.onMenuShareAppMessage(shareData)
...
});
// 微信預(yù)加載失敗回調(diào)
wx.error(function (res) {
console.log(res);
// alert('失敗');
});
}
}).catch(error => {
// 請求接口失敗回調(diào)函數(shù)
})
}
分享成功截圖
本文實踐采坑原創(chuàng)裆赵,轉(zhuǎn)載請注明出處