每回遇到微信分享都是一個坑,目前的商城項目使用Vue開發,采用history的路由模式,配置微信分享又遇到了很多問題,最后終於解決了,現將解決的過程分享一下。
技術要點
Vue,history模式
常見問題及說明
debug模式下報false
這個沒得說,就是調用wx.config
方法的參數錯誤造成的,請確認以下事項:
- 是否成功綁定了域名(域名校驗文件要能被訪問到)
- 使用最新的js-sdk文件,因為微信會改部分api
- config方法的參數是否傳正確了(拼寫錯誤、大小寫...)
- 需要使用的方法是否寫在了
jsApiList
中 - 獲取簽名的url需要
decodeURIComponent
- 后台的生成簽名的加密方法需要對照官方文檔
debug返回ok,分享不成功
- 確保代碼拼寫正確
- 分享鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
- 接口調用需要放在
wx.ready
方法中
單頁項目(SPA)中的一些要點
所有需要使用JS-SDK的頁面必須先注入配置信息,否則將無法調用(同一個url僅需調用一次,對於變化url的SPA的web app可在每次url變化時進行調用,目前Android微信客戶端不支持pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題會在Android6.2中修復)。
上面那段話摘自官方文檔
開發者需要注意的事項:
- android和ios需要分開處理
- 需要在頁面url變化的時候重新調用
wx.config
方法,android獲取簽名的url就傳window.location.href
- Vue項目在切換頁面時,IOS中瀏覽器的url並不會改變,依舊是第一次進入頁面的地址,所以IOS獲取簽名的url需要傳第一次進入的頁面url
Code
router/index.js
......
|
|
import { wechatAuth }
from "@/common/wechatConfig.js";
|
|
......
|
|
const router =
new Router({
|
|
mode: "history",
|
|
base: process.env.BASE_URL,
|
|
routes: [
|
|
{
|
|
path: "/",
|
|
name: "home",
|
|
meta: {
|
|
title: "首頁",
|
|
showTabbar: true,
|
|
allowShare: true
|
|
},
|
|
},
|
|
{
|
|
path: "/cart",
|
|
name: "cart",
|
|
meta: {
|
|
title: "購物車",
|
|
showTabbar: true
|
|
},
|
|
component: () => import("./views/cart/index.vue")
|
|
}
|
|
......
|
|
]
|
|
});
|
|
router.afterEach(
(to, from) => {
|
|
let authUrl = `${window.location.origin}${to.fullPath}`;
|
|
let allowShare = !!to.meta.allowShare;
|
|
if (!!window.__wxjs_is_wkwebview) {// IOS
|
|
if (window.entryUrl == "" || window.entryUrl == undefined) {
|
|
window.entryUrl = authUrl; // 將后面的參數去除
|
|
}
|
|
wechatAuth(authUrl,
"ios", allowShare);
|
|
}
else {
|
|
// 安卓
|
|
setTimeout(
function () {
|
|
wechatAuth(authUrl,
"android", allowShare);
|
|
},
500);
|
|
}
|
|
});
|
代碼要點:
- meta中的allowShare用於判斷頁面是否可分享
- window.__wxjs_is_wkwebview可用來判斷是否是微信IOS瀏覽器
- entryUrl是項目第一次進入的頁面的地址,將其緩存在window對象上
- 為什么安卓的時候要增加一個延時器,因為安卓會存在一些情況,就是即便簽名成功,但是還是會喚不起功能,這個貌似是一個比較穩妥的解決辦法
wechatConfig.js
import http from "../api/http";
|
|
import store from "../store/store";
|
|
export const wechatAuth = async (authUrl, device, allowShare) => {
|
|
let shareConfig = {
|
|
title: "xx一站式服務平台",
|
|
desc: "xxxx",
|
|
link: allowShare ? authUrl : window.location.origin,
|
|
imgUrl: window.location.origin + "/share.png"
|
|
};
|
|
let authRes = await http.get("/pfront/wxauth/jsconfig", {
|
|
params: {
|
|
url: decodeURIComponent(device == "ios" ? window.entryUrl : authUrl)
|
|
}
|
|
});
|
|
if (authRes && authRes.code == 101) {
|
|
wx.config({
|
|
//debug: true,
|
|
appId: authRes.data.appId,
|
|
timestamp: authRes.data.timestamp,
|
|
nonceStr: authRes.data.nonceStr,
|
|
signature: authRes.data.signature,
|
|
jsApiList: ["updateAppMessageShareData", "updateTimelineShareData", "onMenuShareAppMessage", "onMenuShareTimeline"]
|
|
});
|
|
wx.ready(
() => {
|
|
wx.updateAppMessageShareData({
|
|
title: shareConfig.title,
|
|
desc: shareConfig.desc,
|
|
link: shareConfig.link,
|
|
imgUrl: shareConfig.imgUrl,
|
|
success: function () {//設置成功
|
|
//shareSuccessCallback();
|
|
}
|
|
});
|
|
wx.updateTimelineShareData({
|
|
title: shareConfig.title,
|
|
link: shareConfig.link,
|
|
imgUrl: shareConfig.imgUrl,
|
|
success: function () {//設置成功
|
|
//shareSuccessCallback();
|
|
}
|
|
});
|
|
wx.onMenuShareTimeline({
|
|
title: shareConfig.title,
|
|
link: shareConfig.link,
|
|
imgUrl: shareConfig.imgUrl,
|
|
success: function () {
|
|
shareSuccessCallback();
|
|
}
|
|
});
|
|
wx.onMenuShareAppMessage({
|
|
title: shareConfig.title,
|
|
desc: shareConfig.desc,
|
|
link: shareConfig.link,
|
|
imgUrl: shareConfig.imgUrl,
|
|
success: function () {
|
|
shareSuccessCallback();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
function shareSuccessCallback() {
|
|
if (!store.state.user.uid) {
|
|
return false;
|
|
}
|
|
store.state.cs.stream({
|
|
eid: "share",
|
|
tpc: "all",
|
|
data: {
|
|
uid: store.state.user.uid,
|
|
truename: store.state.user.truename || ""
|
|
}
|
|
});
|
|
http.get(
"/pfront/member/share_score", {
|
|
params: {
|
|
uid: store.state.user.uid
|
|
}
|
|
});
|
|
}
|
總結
原先計划不能分享的頁面就使用hideMenuItems方法隱藏掉相關按鈕,在ios下試了一下,有些bug:顯示按鈕的頁面切換的影藏按鈕的頁面,分享按鈕有時依然存在,刷新就沒問題,估計又是一個深坑,沒精力在折騰了,就改為隱私頁面分享到首頁,公共頁面分享原地址,如果有什么好的解決辦法,請聯系我!
一開始我有參考sf上的一篇博客https://segmentfault.com/a/1190000014455713,按照上面的代碼,android手機都能成功,但是IOS有一個奇怪的問題,就是分享間歇性的失效,同一個頁面,剛剛調起分享成功,再試一次就失敗(沒有圖標、title,只能跳轉到首頁),經過“不斷”努力的嘗試,應該是解決了問題,說一下過程:
- 一開始以為是異步喚起沒成功的問題,就和android一樣給IOS調用wechatAuth方法也加了個定時器,測了一遍沒效果,放棄
- 起始js-sdk是通過npm安裝的,版本上帶了個test,有點不放心,改為直接使用script標簽引用官方的版本
- 重新讀了一遍文檔,發現onMenuShareTimeline等方法即將廢棄,就把jsApiList改為
jsApiList:['updateAppMessageShareData','updateTimelineShareData']
,改后就變成了IOS可以成功,android分享失敗
- 百度updateAppMessageShareData安卓失敗原因,參考這個鏈接https://www.jianshu.com/p/1b6e04c2944a,把老的api也加到jsApiList中,仔細、反復試了試兩種設備都ok,好像是成功了,說"好像"是因為心里沒底啊,各種“魔法”代碼!
最后,在這里希望騰訊官方能不能走點心,更新文檔及時點,demo能不能提供完整點....
參考鏈接
https://segmentfault.com/a/1190000014455713
https://www.jianshu.com/p/1b6e04c2944a