G4.01.2uncertain back target on cross-origin entry设计研究

跨来源进入时返回的目标不确定

别名: 跨来源返回 · empty history stack · 外链进入 · referrer back

概念解释

用户从搜索引擎、广告、邮件、推送或另一个站点的 deep link 掉进产品内部某一页时,当前页往往是这个浏览上下文里的第一帧。点返回,目标可能是站外上一页、空白的新标签、被关掉的容器,或被 SPA routing 改写成的某个默认首页。跨来源进入时返回的目标不确定:不是「上一页和上一级搞混了」,而是 history stack 在入站这一刻根本没有一条产品内部的合理上一帧。人仍然会按那个左箭头,以为能回到「进来之前所在的地方」。

机制

浏览器的返回只承诺弹出栈顶,不承诺栈顶属于你的产品。新标签打开的落地页栈里常常只有这一页,Back 直接禁用或关掉标签;从 Google 点进来的,栈顶是 SERP,一返回人就离开了。App 里情况更硬:通知把 activity 单拉起来,back stack 是空的,系统 Back 的默认动作是销毁任务,看起来像闪退。产品若在此时用 history.back()finish(),等于把去留交给一个自己没写过的上一帧。

不确定还会被路由策略放大。落地页若 replaceState 成内部规范 URL,站外来源从栈上消失,Back 变成站内某处;若同时自动再跳一次登录或地区选择,栈上多出用户没点过的帧,Back 会先落到这些拦截页,而不是来源。人无法预演下一次返回会去哪,因为来源不是界面的一部分,也没有被说出来。

怎么研究

跨入口返回任务:同一 URL 分别从站内导航、搜索引擎模拟、邮件深链、空的新标签打开,点系统返回,记录落点和被试事先写出的预期。

  • 自变量:来源类型、打开方式(当前标签 / 新标签 / App 任务)、入站时路由是 push、replace 还是又套了一层拦截页。
  • 因变量:落点与预期一致、意外离开产品的次数、返回后无法解释「我为什么在这」的口头报告。
  • 方法论注意点:实验室若总从站点首页点进去,跨来源条件根本没出现。邮件和推送要用真实的冷启动,不要在已有任务栈的会话里点通知。Weinreich、Obendorf 等人的 Web 日志反复显示大量会话以外部搜索进入——内部树测试覆盖不到这条失败。

边界

用户是从本产品的另一个页面点过来的,栈顶是确定的内部帧,这条不成立,应回到时间性返回本身。Safari 等浏览器对跨站 Back 的 bfcache 和隐私限制会让「回到来源」也失败,来源页被冻结或需重载,不确定来自浏览器而不是产品路由。受控的 WebView(支付中转、OAuth)故意把返回交给容器关闭,这时不确定是协议要求,需要的是关闭而非伪造一条内部上一页。

怎么落地

  • 入站时检测 history.length 或 App 任务栈是否为空。空栈不要调用 back();给一条站内合理出口(该类目、搜索框、首页),文案写成去处的名字,而不是「返回」。
  • 从已知外部来源进入时,不要用 replace 抹掉那一帧,除非紧接着必须进入登录;登录完成应用 replace 清掉拦截页,避免 Back 卡在登录。
  • 通知与邮件打开的页,预先为任务指定父级栈(该类目或列表),让系统 Back 有内部帧可弹,而不是直接 finish。
  • 验证:用无痕窗口从外部搜索打开落地页,点返回,记录是离开、留在空白标签,还是落到产品自己声称的位置。再用杀进程后的通知冷启动测一次。两条路径的落点都要能事先用一句话说清。

延伸

  • 同组G4.01.1 返回上一页与返回上一级是两种语义 · G4.01.3 返回后应恢复原页面的状态
  • 相邻G4.02 深链接 · G4.04 新窗口与原地跳转 · G2.07 导航的一致性
  • 站内检索cross-origin entry · empty back stack · deep link

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/G4.01.2