fix(h5-shop): harden iOS WeChat scan after login with hard nav and recover UI

Root cause is JSSDK entry-URL mismatch after SPA post-OAuth, not camera permission. Hard-navigate on iOS, keep OAuth query in sign URL, skip redundant bind OAuth, and prompt refresh/re-auth on failure.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-07 13:08:13 +08:00
parent 2a9493165b
commit e4e9eb2169
12 changed files with 192 additions and 47 deletions
+34
View File
@@ -0,0 +1,34 @@
# @dukang/weixin-sdk · 踩坑
## iOS 微信 H5JSSDK 入场 URL(扫码 / 定位 / 选图)
### 症状
- 登录或 OAuth 后立刻调 `scanQRCode` / `getLocation` / `chooseImage` 失败
- 错误类似:`permission value is offline verifying``invalid signature`
- 业务文案常被写成「权限校验尚未完成,请等 1~2 秒」——**多数情况下等无效**
- 关掉 webview 再进(整页重载)立即恢复
### 原因
iOS 微信对 JS-SDK 验签使用的是**本次 document 加载时的 URL**(去掉 `#` 后的完整 URL**含 query**)。
`history.pushState` / `replaceState`(含 React Router)**不会**更新微信内部用于验签的 URL。
典型错误链路:
1. OAuth 回跳:`/login?code=xxx&state=yyy`(入场 URL
2. SPA`navigate('/')`
3. 用当前页 `/` 或「去掉 code 后的 `/login`」去签名 → 与微信内部 URL 不一致 → 失败
### 正确做法
1. **业务跳转(登录成功 / 选店进首页)**iOS 微信内用 `hardNavigateInWechat(path)` / `location.replace`,让目标页成为新的入场 URL。
2. **签名 URL**`getJssdkSignUrl()` 在 iOS 上返回入场 URLOAuth 的 `code/state` **必须保留**参与签名;后端 `jssdk-config` 只去 `#`,不要删 query。
3. **先 `captureIosJssdkEntryUrl()`,再 `stripOAuthParamsFromLocation()`**
4. 失败恢复:引导用户刷新页面或重新走 OAuth,而不是无限「再点一次」。
### 相关 API
- `captureIosJssdkEntryUrl` / `getJssdkSignUrl`
- `shouldHardNavigateForJssdk` / `hardNavigateInWechat`
- `stripOAuthParamsFromLocation`