每回遇到微信分享都是一個坑,目前的商城專案使用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上的一篇部落格segmentfault.com/a/119000001…,按照上面的程式碼,android手機都能成功,但是IOS有一個奇怪的問題,就是分享間歇性的失效,同一個頁面,剛剛調起分享成功,再試一次就失敗(沒有圖示、title,只能跳轉到首頁),經過“不斷”努力的嘗試,應該是解決了問題,說一下過程:
-
一開始以為是非同步喚起沒成功的問題,就和android一樣給IOS呼叫wechatAuth方法也加了個定時器,測了一遍沒效果,放棄
-
起始js-sdk是通過npm安裝的,版本上帶了個test,有點不放心,改為直接使用script標籤引用官方的版本
-
重新讀了一遍文件,發現onMenuShareTimeline等方法即將廢棄,就把jsApiList改為
jsApiList:['updateAppMessageShareData','updateTimelineShareData']
,改後就變成了IOS可以成功,android分享失敗 -
百度updateAppMessageShareData安卓失敗原因,參考這個連結www.jianshu.com/p/1b6e04c29…,把老的api也加到jsApiList中,仔細、反覆試了試兩種裝置都ok,好像是成功了,說"好像"是因為心裡沒底啊,各種“魔法”程式碼!
最後,在這裡希望騰訊官方能不能走點心,更新文件及時點,demo能不能提供完整點....
參考連結
segmentfault.com/a/119000001… www.jianshu.com/p/1b6e04c29… segmentfault.com/a/119000001… github.com/vuejs/vue-r…