Files
wx-h5-demo/README.md
Karlcarlo 0399fd00ff wx-h5-demo: 顶部新增「返回首页」6 个按钮 —— 演示身份怎么带过去 (demo v26092201)
按接入规范(box_app/docs/h5-auth-standard.md 第三节第 6 条同源身份缓存、
第五节第 6 条回首页不要裸跳)把这条路径做成可点的验证工具:

  ① goHome()                —— 规范推荐,库自己带身份
  ② 手拼 URL 带 openid/unionid —— 规范做法,身份放 query
  ③ 裸跳 /mama-box/(反例)      —— URL 无身份;靠同源缓存兜底通常仍认得
  ④ switchTab 回小程序首页壳    —— 宿主重新注入,最稳(仅 web-view 内)
  ⑤ 清同源缓存 + 裸跳           —— **复现线上 bug**:首页「身份不完整」且重试救不回
  ⑥ 清同源缓存 + goHome()       —— 证明 goHome 主动带身份、不依赖缓存

实现要点:
- 卡片放在页面顶部(.env 那行之后);新增一行只读展示 identity() 的 from/openid/unionid。
- ②③⑤ 用**同源相对地址**(location.origin + '/mama-box/'):同源缓存本来就只在本 origin
  有效,这样写与生产等价且可被其它挂载点复用;①⑥ 仍走库的 goHome()(绝对地址)——那正是要演示的 API。
- clearIdCache() 清完**不再**调 identity() 刷新展示:本页 URL 上还带着身份,"URL 优先"会立刻
  写回缓存,等于白清(本地实测踩过,⑤ 因此复现不出来)。
- dbg() 已镜像 console.log:这些按钮点下去就跳走,页内面板看不到日志。

本地同源验证(/wx-h5-demo + /mama-box 同一 origin、桩后端):②③⑥ 落地无「身份不完整」;
⑤ 落地**提示条 flex**(bug 复现);① 走库的 goHome() 带 ?openid= 落地正常。页面无 JS 异常。
2026-09-22 21:52:16 +08:00

100 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# wx-h5-demo · 独立示例 H5(小程序授权 / 跳转)
> 独立二级目录项目,由 box_app 挂载到 `/wx-h5-demo`(即 `https://mp.yizhezhe.com/wx-h5-demo/`)。
> 配套说明:`docs/h5-miniprogram-auth.md`。
## 两种场景
| 场景 | 流程 | 用到的小程序页 |
| --- | --- | --- |
| **场景1** | 微信(浏览器)打开 H5 链接 → 跳**小程序授权页**授权 → 授权后小程序用 web-view 加载本 H5(结果在 URL)→ “回到 H5” | `miniapp/scenario1-auth-bridge.*`(授权桥页) |
| **场景2** | 微信跳到**小程序 web-view 的 H5 应用** → H5 `postMessage` 请求授权 → 宿主弹原生授权面板 → 授权 → 更新 `web-view src`(带结果)→ H5 重载显示 | `miniapp/scenario2-host-page.*`(web-view 宿主页) |
| **场景3** | web-view 里的 H5 **分享给微信好友** → 接收者应打开**发送者当时那一页**(含 hash/SPA 深链),而不是小程序首页 | `miniapp/scenario3-share-webview.*`(✅ 正确宿主页)、`miniapp/scenario3-home-bug.*`(❌ 反面首页,复现 bug) |
> 说明:场景2 的宿主页 `scenario2-host-page` 同时是场景1 授权后 redirectTo 的落地页(从 `globalData` 读结果拼 H5 url)。
## 返回首页 · 身份怎么带过去(2026-09-22 新增,页面顶部那张卡)
6 个按钮,用来验证「H5 返回首页」时身份怎么带过去、以及什么时候会丢:
| 按钮 | 做法 | 预期落地表现 |
| --- | --- | --- |
| ① | `wxAuth.goHome()` | 首页**认得你**(库自己带上身份,规范推荐) |
| ② | 手拼 URL 带 `openid/unionid` | 首页**认得你**(规范做法;身份放 query) |
| ③ | 裸跳 `/mama-box/`(**反例**) | URL 上没身份,但**同源缓存兜底**通常仍认得你 —— 那是兜底生效,不是这条跳法对 |
| ④ | `wx.miniProgram.switchTab('/pages/index/index')` | 回**小程序首页壳**,由宿主重新注入身份(最稳,仅 web-view 内可用) |
| ⑤ | 清同源缓存 + 裸跳 | **复现线上 bug**:首页出现「身份不完整」提示条,且**点重试也救不回** |
| ⑥ | 清同源缓存 + `goHome()` | 仍**认得你**(`goHome` 主动带身份,不依赖缓存) |
原理与硬约定见 `box_app/docs/h5-auth-standard.md` **第三节第 6 条**(同源身份缓存)与**第五节第 6 条**(回首页不要裸跳)。
⚠️ 缓存写在 `sessionStorage['mmbox.identity']`,**只在本 origin 内有效**(本页与 mama-box 同在 `mp.yizhezhe.com`);
外链域名的应用读不到,必须自己带身份。
⚠️ 点下去就 `location.href` 跳走,**页内调试面板看不到日志**(随页面销毁)——`dbg()` 已镜像到 `console.log('[dbg]', …)`,
真机上看 console 或用上面的 `[wxAuth]` 日志。
## 文件
```
wx-h5-demo/
├─ index.html # 示例 H5(自包含):环境检测(webview/微信浏览器/纯浏览器)、
│ # 场景1 跳小程序授权 或 场景2 postMessage 授权、读回传参数展示、
│ # 场景3 分享深链验证(正确分享 / 复现旧 bug 两个按钮)。
├─ miniapp/
│ ├─ scenario1-auth-bridge.wxml/.js # 场景1 小程序授权桥页(launch-weapp/URL Scheme 进入)
│ ├─ scenario2-host-page.wxml/.js # 场景2 web-view 宿主页(也作场景1 落地页)
│ ├─ scenario3-share-webview.wxml/.js # 场景3 ✅ 正确:onShareAppMessage(options).webViewUrl 拼深链
│ └─ scenario3-home-bug.wxml/.js # 场景3 ❌ 反面:写死 path 的「首页」,复现「分享跳首页」
└─ README.md
```
## 怎么做
1. **H5**:改 `index.html`(H5 地址 = `https://mp.yizhezhe.com/wx-h5-demo/`)。
2. **小程序端**:把 `miniapp/*` 的两个页面代码并入你的小程序(如 CRMEB),改 3 处:
- `app.globalData.openid`(登录态)。
- `H5_BASE` 指向你的 H5。
- `https://YOUR_API/phone|avatar`(或注释里说明;手机号 `code`→后端换明文;头像需上传换正式地址)。
3. **入口**:
- 场景2:宿主页已用 `<web-view src="{{url}}">` 加载 H5,H5 点「在 web-view 里请求授权」即可。
- 场景1:H5 点「去小程序授权」→
- **小程序 web-view 内**:已内置 `wx.miniProgram.navigateTo({url:'/pages/demo/auth'})`(无需 scheme)。
- **微信浏览器(非 web-view)**:给 `LAUNCH_SCHEME` 填一个**小程序 URL Scheme**(后端用 appid+path 换),或把页面放进公众号/网页用 `<wx-open-launch-weapp path="/pages/demo/auth">`(需 jsapi 签名,并在微信内打开)。
- 场景1 能真正走通的前提:**你的小程序里要有 `/pages/demo/auth`(= `miniapp/scenario1-auth-bridge.*`)和 `/pages/demo/webview`(=`scenario2-host-page.*`),并在 `app.json` 注册这两个页面**;否则 navigateTo 会「页面不存在」。
## 验证分享深链(场景3)· 2026-09
> 症状:web-view 里的 H5 分享给微信好友后,接收者点开卡片落到**小程序首页**,不是对应的 H5 页面。
### 先记住平台约束
- web-view 里的 H5 **不能自己拉起分享面板**;卡片只能由承载 `<web-view>` 的**宿主小程序页**的
`onShareAppMessage` 产出。
- `onShareAppMessage(options)` 的 **`options.webViewUrl`** 才是当前 web-view 的真实地址
(含 H5 的 hash / SPA 路由)—— 这是唯一可靠的深链来源。
- `wx.miniProgram.postMessage` **不是实时投递**,只在「后退 / 组件销毁 / 分享」等时机批量派发,
不能拿它的 `href` 当深链来源。
- **禁止**在 H5 分享时调 `wx.miniProgram.navigateBack()`(旧版 `bridge.share` 为了“触发投递”这么干,
它会把 web-view 页弹掉,转发被上一页接管 → 接收者进首页)。
### A. 在真机 CRMEB 小程序里验证(推荐,无需注册 demo 页)
1. 用 CRMEB 小程序打开:`/pages/annex/web_view/index?url=https%3A%2F%2Fmp.yizhezhe.com%2Fwx-h5-demo%2F`
(或在「我的应用 / 应用宫格」里点 `wx-h5-demo`)。
2. H5 里点 ①「生成唯一深链标记」→ 记录页面地址里的 `#/share-probe/xxxx`。
3. 点 ②「✅ 正确分享」→ 本页应**停留不动** → 点右上角「···」转发。
4. 用另一个微信号点开卡片:应打开**同一个地址**(能看到相同 `#/share-probe/xxxx`),不是首页。
5. 反向对照:重来一次,第 3 步改点 ③「❌ 复现旧 bug:postMessage + navigateBack」,
会立刻退回上一页;此时再转发,接收者就落到那个上一页(bug 复现)。
### B. 用独立 demo 小程序页验证
把 `miniapp/scenario3-home-bug.*`(路径 `/pages/demo/home`)和
`miniapp/scenario3-share-webview.*`(路径 `/pages/demo/share-webview`)并入你的小程序并在 `app.json` 注册,
以 `/pages/demo/home` 为起点:本页 → 进 web-view → H5 点 ③ → 退回本页 → 转发(bug 复现);
改点 ② → 停留 web-view → 转发(接收者进 H5)。对照 `scenario3-share-webview.js` 与
`scenario3-home-bug.js` 两个 `onShareAppMessage` 的差别即可。
> 线上真实实现:`CRMEB pages/annex/web_view/index.vue`(容器)与 `pages/index/index.vue`(首页壳),
> 见 `crmeb/docs/分享图片获取逻辑.md` 第四节。
## 注意
- 手机号:前端只拿 `code`,**明文必须后端** `wx.business.getuserphonenumber` 换(旧 `code2Session`+解密已收紧)。
- 头像:`e.detail.avatarUrl` 是临时 URL,需 `wx.uploadFile` 上传存后端,回传正式地址。
- `getUserProfile` 已废弃(匿名);用 `getPhoneNumber` / `<input type="nickname">` / `chooseAvatar`。
- 身份:保留 `openid`(query);授权结果走 **hash**(`#phone/nickname/avatar`,微信 webview 丢 query 不丢 hash)。
- 纯浏览器打开 `index.html`:仅 UI 演示(有降级提示),无法真授权。