// 场景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=;否则加载默认 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)) }; } });