vue history模式微信自定義分享

2020-10-25 10:02:00

history模式微信自定義分享

前言

最近做的Vue SPA專案涉及到微信自定義分享,最初只是在指定頁面下實現微信的二次分享功能。但是因為行動端使用的是vue-routerhistory模式,所以在iOS端微信和Android端微信分享出來的截然不同,大多數是iOS端微信會分享失敗。上網查詢了一些檔案說是iOS端微信不支援pushState的H5新特性。還有就是iOS端微信記錄的URL是首次存取網頁時的網址,所以在使用window.location.href獲取當前網址來換取微信的簽名校驗資訊時候就會導致簽名校驗失敗,致使最終微信分享失敗。

解決方案

iOS端微信處理方法:儲存首次進入頁面時候的路徑,在需要呼叫微信分享的頁面內利用首次進入頁面時候的路徑URL來換取iOS端微信分享的簽名。
Android端微信處理方法:Android端微信每次切換路由時候都會重新整理頁面,故在需要使用微信分享的頁面直接獲取當前頁面所在路徑的URL即使用window.location.href來換取微信分享的簽名即可。

判斷iOS、Android裝置方法

Android裝置環境:

let ua = navigator.userAgent;
// 方法一
let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
// 方法二
let isAndroid = ua.indexOf('Android') > -1 || ua.indexOf('Adr') > -1; 
// 方法三
let isAndroid = /(Android)/i.test(navigator.userAgent);

iOS裝置環境:

// 方法一
let isiOS = !!window.__wxjs_is_wkwebview;
// 方法二
let isiOS = /iPhone|mac|iPod|iPad/i.test(navigator.userAgent);
// 方法三
let u = navigator.userAgent;
let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); 

主要程式碼

  • 封裝wxShare.js
import axios from "axios";
import store from "../store";
/* 微信自定義分享 */
/**
 * url:獲取微信分享簽名的url地址
 * device:iOS&Android裝置的區分
 * isShare:當前所在路徑是否需要分享
 *  */ 
const WeChatShare = (url, device, isShare) => {
    if (!isShare) {
        return;
    }
    let xxx = store.state.xxx;
    let shareLink = window.location.origin + "?xxx=" + xxx;
    if (store.state.xxxx == "") {
        return;
    }
    let { title, imgUrl, link, desc } = store.state.xxxx;
    if (device == "iOS") {
        // 獲取iOS微信首次儲存的URL
        url = sessionStorage.getItem("iOS-URL");
    } else {
        url = window.location.href;
    }
    if (url.includes("#")) {
        url = url.split("#")[0];
    }
    // 獲取時間戳
    axios
        .get("wx/api", { params: { url: decodeURIComponent(url) } })
        .then(res => {
            if (res.data.code == 1) {
                let { timestamp, noncestr, signature } = res.data.result_data;
                // 校驗
                wx.config({
                    debug: false,
                    appId: "appId",
                    timestamp: timestamp,
                    nonceStr: noncestr,
                    signature: signature,
                    jsApiList: ["checkJsApi", "updateAppMessageShareData", "updateTimelineShareData"]
                });
                // 檢測
                wx.ready(() => {
                    wx.checkJsApi({
                        jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"],
                        success: function (res) { }
                    });
                    // 自定義「分享給朋友」及「分享到QQ」(1.4.0)
                    wx.updateAppMessageShareData({
                        title: title,
                        desc: desc,
                        link: link,
                        imgUrl: imgUrl,
                        success: () => { }
                    });
                    // 自定義「分享到朋友圈」及「分享到QQ空間」(1.4.0)
                    wx.updateTimelineShareData({
                        title: title,
                        link: link,
                        imgUrl: imgUrl,
                        success: () => { }
                    });
                });
            }
        })
        .catch(err => {
            console.log("JSSDK share error:", err);
        });
};
  • 分享連結處理
/* 處理分享連結 */
const shareLink = location => {
    let origin = location.origin,
        search = location.search;
    if (search.includes("&")) {
        search = search.split("&")[0];
    }
    let link = origin + search;
    return link;
};
  • router.js多路徑自定義分享設定
// 裝置判斷
let ua = navigator.userAgent;
// Android
let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
// iOS
let isIos = !!window.__wxjs_is_wkwebview;
// 微信二次分享
router.afterEach((to, from) => {
    let authUrl = `${window.location.origin}${to.fullPath}`;
    let allowShare = !!to.meta.allowShare;
    // IOS
    if (isIos) {
        authUrl = sessionStorage.getItem("iOS-URL");
        WeChatShare(authUrl, "iOS", allowShare);
    }
    // Android
    if (isAndroid) {
        setTimeout(() => {
            WeChatShare(authUrl, "android", true);
        }, 400);
    }
});

注:
在vue專案中只是分享某一個路徑下的頁面,即可在當前頁面路徑下引入寫好的微信分享檔案方法,在需要分享的頁面進行呼叫即可。
Vue SPA專案 history模式中,指定頁面需要實現動態分享,其餘路徑頁面實現固定分享,既可以在router.js的 router.afterEach((to,from)=>{}) 全域性生命週期勾點函數中呼叫微信分享方法即可實現指定路徑頁面動態分享,其餘路徑頁面固定分享的需求。
hash模式,直接按照Android端微信的呼叫方式即可。如有問題,可依據此思路作為參考,並結合實際需求進行相應的調整。