fix(util): 修复内部页面绝对URL被误判为外链的问题

新增extractInternalAppPath和resolveNavMode工具函数,在diyRedirectTo中增加内部页面绝对URL还原逻辑:
1. 支持通过open_mode配置三种导航模式:auto/online/internal
2. 严格校验域名避免误伤外部站点,支持强制内部跳转场景
3. 修复H5整页刷新丢失状态、MP被塞进web-view的问题
This commit is contained in:
2026-07-16 16:32:10 +08:00
parent 61e7a0d859
commit cf6d54e2bf
3 changed files with 307 additions and 18 deletions

View File

@@ -17,6 +17,8 @@ import {
cleanParamUrls,
normalizeUrl as _normalizeUrlBase,
appendQueryParams as _appendQueryParamsBase,
extractInternalAppPath as _extractInternalAppPath,
resolveNavMode as _resolveNavMode,
_shouldEncodeUrl,
_safeEncodeForPlatform,
_navigateTo,
@@ -1092,6 +1094,42 @@ export default {
link.wap_url = resolvedUrl;
}
// 修复: 内部页面被后台存成【绝对 URL】(如 https://host/hwappx/common/pages_tool/form/formdata)
// 时,下方 `indexOf('http') != -1` 会把它误判为"外部链接":
// - H5 走 window.location.href → 整页刷新,点返回时整个 App 重启、启动屏重播、状态/滚动丢失
// - MP 走 web-view → 本应原生跳转的内部页被塞进 web-view
// 这里把"指向本 App 内部页面"的绝对 URL 还原为相对路径,使其改走下方内部页面分支(SPA 跳转)。
//
// 由 open_mode 统一控制(顶层字段 或 page_params):
// - 'auto'(默认): 双闸门 —— host 与本 App 域名【完全一致】且路径带 /pages 段才还原。
// 不同子域/不同域名一律当外链,彻底避免误伤 Shopify、Facebook 等外站。
// - 'internal': 强制内部 —— 跳过 host 校验, 只要路径带 /pages 段就还原为 SPA 跳转。
// 用途: 数据里链接域名与当前部署域名不同(如 xcx3 vs xcx6)但确认是同一 App 内部页。
// - 'online': 强制线上 —— 不还原, 保持整页刷新 / web-view。
// 用途: 某些自域名页面是非 SPA / 遗留页,必须整页或 web-view 打开。
if (link.wap_url && /^https?:\/\//i.test(link.wap_url)) {
const navMode = _resolveNavMode(link); // 'internal' | 'online' | 'auto'
if (navMode !== 'online') {
let internalPath;
if (navMode === 'internal') {
// 强制内部: 传 true 跳过 host 校验
internalPath = _extractInternalAppPath(link.wap_url, true);
} else {
// auto: host 完全一致才还原
const appHosts = [];
// #ifdef H5
try { if (typeof location !== 'undefined' && location.hostname) appHosts.push(location.hostname); } catch (e) {}
// #endif
try { if (Config.h5Domain) appHosts.push(Config.h5Domain); } catch (e) {}
try { if (Config.baseUrl) appHosts.push(Config.baseUrl); } catch (e) {}
internalPath = _extractInternalAppPath(link.wap_url, appHosts);
}
if (internalPath) {
link.wap_url = internalPath;
}
}
}
// 外部链接
if (link.wap_url && link.wap_url.indexOf('http') != -1) {
// 公共参数 + 透传 page_params(resolveLinkUrl 已把 wap_url 中的 query 合并到 page_params)