85 lines
3.7 KiB
JavaScript
85 lines
3.7 KiB
JavaScript
// 场景3(✅ 正确实现):web-view 承载 H5 + 分享深链
|
||
// 路径:/pages/demo/share-webview.js
|
||
// ------------------------------------------------------------
|
||
// 关键点:web-view 里的 H5 不能自己拉起分享面板,卡片只能由本页的
|
||
// onShareAppMessage 产出。深链必须取微信回调参数
|
||
// options.webViewUrl(= 当前 web-view 的真实地址,含 H5 的 hash / SPA 路由),
|
||
// 再拼回本页 ?url=...,接收者打开的就是「发送者当时那一页」,而不是首页。
|
||
//
|
||
// ❌ 反面写法(复现 bug):scenario3-home-bug.js —— 写死 path、忽略 webViewUrl。
|
||
// 线上真实实现见 CRMEB:pages/annex/web_view/index.vue、pages/index/index.vue。
|
||
const H5_BASE = 'https://mp.yizhezhe.com/wx-h5-demo/';
|
||
|
||
// 剥掉分享链接里的身份/缓存参数:不能把发送者的 openid 带给接收者,
|
||
// 接收者身份由宿主页/容器按自己的 openid 重新注入。
|
||
const SHARE_DROP_KEYS = ['openid', 'unionid', 't', '_v', 'phone', 'nickname', 'avatar'];
|
||
function dropKeyValuePairs(str, keys) {
|
||
return String(str || '')
|
||
.split('&')
|
||
.filter(p => !!p && keys.indexOf(p.split('=')[0]) === -1)
|
||
.join('&');
|
||
}
|
||
function stripAuthParams(url) {
|
||
let out = String(url || '');
|
||
const hashIdx = out.indexOf('#');
|
||
let base = hashIdx >= 0 ? out.slice(0, hashIdx) : out;
|
||
let hash = hashIdx >= 0 ? out.slice(hashIdx + 1) : '';
|
||
const qIdx = base.indexOf('?');
|
||
let query = qIdx >= 0 ? base.slice(qIdx + 1) : '';
|
||
base = qIdx >= 0 ? base.slice(0, qIdx) : base;
|
||
query = dropKeyValuePairs(query, SHARE_DROP_KEYS);
|
||
hash = dropKeyValuePairs(hash, SHARE_DROP_KEYS);
|
||
return base + (query ? '?' + query : '') + (hash ? '#' + hash : '');
|
||
}
|
||
|
||
Page({
|
||
data: { url: '', shareTitle: '', shareImageUrl: '' },
|
||
|
||
onLoad(options) {
|
||
// 开启「转发给好友 / 分享到朋友圈」两项菜单
|
||
wx.showShareMenu({ menus: ['shareAppMessage', 'shareTimeline'] });
|
||
|
||
// 被分享卡片打开时带 ?url=<encoded 当前 H5 地址>;否则加载默认 H5
|
||
let target = H5_BASE;
|
||
if (options && options.url) {
|
||
try { target = decodeURIComponent(options.url); } catch (e) { target = options.url; }
|
||
}
|
||
console.log('[scenario3] 加载 H5:', target);
|
||
this.setData({ url: target });
|
||
},
|
||
|
||
// H5 点「分享」→ postMessage(action:'share') → 这里只缓存标题/图;
|
||
// 链接以 options.webViewUrl 为准(postMessage 投递有延迟,不能当深链来源)。
|
||
onMessage(e) {
|
||
const data = (e.detail && e.detail.data) || [];
|
||
(Array.isArray(data) ? data : [data]).forEach((m) => {
|
||
if (!m || m.action !== 'share') return;
|
||
console.log('[scenario3] H5 请求分享:', JSON.stringify(m));
|
||
if (m.title) this.setData({ shareTitle: m.title });
|
||
if (m.imageUrl) this.setData({ shareImageUrl: m.imageUrl });
|
||
wx.showToast({ title: '点击右上角 ··· 分享给好友', icon: 'none', duration: 2500 });
|
||
});
|
||
},
|
||
|
||
// ✅ 关键:用 options.webViewUrl 拼深链
|
||
onShareAppMessage(options) {
|
||
const target = (options && options.webViewUrl) || this.data.url;
|
||
const path = '/pages/demo/share-webview?url=' + encodeURIComponent(stripAuthParams(target));
|
||
console.log('[scenario3] onShareAppMessage → path=' + path);
|
||
return {
|
||
title: this.data.shareTitle || 'wx-h5-demo · 分享深链验证',
|
||
path: path,
|
||
imageUrl: this.data.shareImageUrl || ''
|
||
};
|
||
},
|
||
|
||
// onShareTimeline 没有回调参数(拿不到 webViewUrl),也不能自定义 path;
|
||
// 只能把目标 H5 放进 query,由本页 onLoad 读 ?url= 落地。
|
||
onShareTimeline() {
|
||
return {
|
||
title: this.data.shareTitle || 'wx-h5-demo · 分享深链验证',
|
||
query: 'url=' + encodeURIComponent(stripAuthParams(this.data.url))
|
||
};
|
||
}
|
||
});
|