Skip to content

边界与限制

支持

  • 首次 install()时命中 scope 的当前业务 entry;
  • install()后命中 scope 的 history.pushState()业务记录;
  • 浏览器工具栏 Back;
  • history.back()history.go(-1)
  • 受保护业务 entry 的普通刷新与连续刷新;
  • 受保护 entry 上重复执行 replaceState()
  • 多 Handler LIFO 栈;
  • 异步 Handler、pending 去重和失效 resolve()
  • 同一模块实例内幂等安装;
  • Chromium、Firefox 和 WebKit。

固定代价

保护当前 entry 会让 history.length增加 1。每次命中 scope 的业务 pushState()会写入一条内部 edge 和一条业务记录,因此 history.length增加 2。 不命中 scope 的 pushState()保持原生行为。受保护 entry 上的公开 replaceState()先完成调用方要求的原生写入,再恢复 Guard 私有锚点;调用方对象、 业务字段、URL 与原生异常语义不变。

补丁和 popstate listener 常驻到 Document 卸载。内部 edge 也不会主动清理;没有 Handler 时由协调器透明跨过。

不保证

  • 当前 entry 之前的既有记录不会被改写或单独保护;
  • Forward 不调用 Handler,只透明跨过受管 edge;
  • location.hash、锚点链接等自动创建的记录;
  • history.go(-N)等多步穿越和长按历史选择;
  • 同一任务中排队的多次穿越或极快的多次工具栏点击;
  • 地址栏导航、关闭标签页或普通刷新以外的跨文档导航;
  • iframe 联合 History;
  • 安装前保存并绕过补丁调用的原生 History 方法;
  • 内部穿越或 Handler pending 时执行 History 写入;
  • History 写入失败后的回滚;
  • IE 或仅支持 ES5 的运行环境。

相对 URL 以当前 URL 为基准交给 scope。原生 pushState()仍负责 state 克隆、 同源校验和公开写入错误。首次公开写入成功后的内部 History 写入失败不提供回滚。 用于保护的根 state 必须是 null、普通对象或数组;其中嵌套的 MapDate、 数组、循环引用和共享引用按浏览器结构化克隆语义保留。锚点非法、版本不支持或找不 到对应 edge 时安全放行,不猜测穿越步数。

Released under the MIT License.