fix(宿主恢复): 返回首页时清除 last_app —— 不再冷启动被送回刚退出的应用 (v26092203)

问题(用户实测):进入 H5 应用(如孕期血糖记录)→ 退回 mama-box 首页 →
再冷启动进小程序,又被送回那个应用。记录的是「最后进入的 H5 应用」,
用户已经回到首页了,首页才是最后待的地方 → 必须清掉。

- clearLastAppOnBackHome():DELETE /api/mp/public/last-app?openid=
- 只认「这次是返回回到本页」三种情形,**不能每次加载都清**(宿主恢复会把本页当返回落点加载,
  那时清掉会毁掉刚用上的记录):
    ① bfcache 恢复 → 复用文件末尾已有的 pageshow 监听(persisted=true)
    ② 后退导致整页重载 → navigation.type === 'back_forward'(init() 里判)
    ③ 从应用页 location.href 回本页 → document.referrer 是 https://mp.yizhezhe.com/<app>/
- 宿主恢复/落点那两次加载都是 navigate + referrer 空 → 不会误清
- 版本 v26092202 → v26092203
This commit is contained in:
2026-09-22 11:56:25 +08:00
parent b71a773476
commit 2c55e6737e
2 changed files with 48 additions and 3 deletions

View File

@@ -7,7 +7,7 @@
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>兜爸心选 · 孕育陪伴</title>
<!-- V:26092202 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
<!-- V:26092203 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
<link rel="stylesheet" href="mama-box.css">
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<!-- 共享助手:授权/跳商城/位置上报(分享卡片同步,见 docs/h5-auth-standard.md 第四节) -->

View File

@@ -3,7 +3,7 @@
(function () {
'use strict';
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
var VER = '26092202';
var VER = '26092203';
const $ = (s, c) => (c || document).querySelector(s);
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
@@ -213,6 +213,46 @@
} catch (e) {}
}
/* ================= 返回首页 → 清除 last_app(2026-09-22) =================
问题:用户进入 H5 应用后又退回 mama-box 首页,但记录还停在那个应用上 ——
下次冷启动(普通入口)会把他又送回刚退出的应用(用户实测)。
记录的是「最后进入的 H5 应用」,用户已经回到首页,那首页才是他最后待的地方 → 必须清掉。
⚠️ 不能用「本页每次加载都清」:宿主恢复时会把 mama-box 当返回落点加载(#norestore=1),
那时清掉会把刚用上的记录毁掉。
所以只认「这次是返回回到本页」的三种情形:
① bfcache 恢复:pageshow 事件 persisted === true(脚本不重跑,只有这个事件)
② 后退导致整页重载:navigation.type === 'back_forward'
③ 从别的 H5 应用页以 location.href 回本页:document.referrer 是 https://mp.yizhezhe.com/<app>/
宿主恢复/返回落点那两次加载都是 navigate + referrer 空 → 不会误清。 */
let _lastAppCleared = false;
function isBackToThisPage() {
try {
const nav = window.performance && performance.getEntriesByType && performance.getEntriesByType('navigation')[0];
if (nav && nav.type === 'back_forward') return true;
} catch (e) {}
try {
const ref = document.referrer || '';
if (ref.indexOf('https://mp.yizhezhe.com/') === 0 && ref.indexOf('/mama-box') === -1) return true;
} catch (e) {}
return false;
}
function clearLastAppOnBackHome(persisted) {
try {
if (_lastAppCleared) return;
if (!persisted && !isBackToThisPage()) return;
const oid = hashParam('openid');
if (!oid) return;
_lastAppCleared = true;
console.log('[enter-app] 返回 mama-box 首页 → 清除 last_app(persisted=' + !!persisted +
',下次冷启动不再回上次那个应用)');
if (window.fetch) {
fetch(LAST_APP_API + '?openid=' + encodeURIComponent(oid), { method: 'DELETE', keepalive: true })
.catch(function () {});
}
} catch (e) {}
}
/* ② 后退重载:脚本会重跑,init() 里调;① bfcache:整页不重载,挂在文件末尾已有的 pageshow 上 */
function goArchiveH5() {
const oid = hashParam('openid');
const uid = hashParam('unionid');
@@ -2495,6 +2535,9 @@
/* ================= 初始化 ================= */
function init() {
/* 返回首页 → 清 last_app(后退重载 / 从应用页 href 回来两种情形;bfcache 由 pageshow 处理)。
放在 resumeLastApp 之前:后退回来的会话里恢复闸门已占住,两者不会打架。 */
clearLastAppOnBackHome(false);
/* 冷启动恢复:读一次 last_app,命中就跳到上次进入的 H5 应用(会话内只尝试一次,
见 resumeLastApp)。放在最前面,尽量少闪一下首页。 */
resumeLastApp();
@@ -3012,7 +3055,9 @@
document.addEventListener('visibilitychange', function () {
if (document.visibilityState === 'visible') resetScreenOnShow();
});
window.addEventListener('pageshow', function () {
window.addEventListener('pageshow', function (e) {
/* bfcache 恢复(persisted=true)= 用户「返回」回到了本页 → 清掉 last_app(见 clearLastAppOnBackHome) */
clearLastAppOnBackHome(!!(e && e.persisted));
if (document.visibilityState !== 'hidden') resetScreenOnShow();
});