嵌入 iframe 的页面 history 流程(浏览器后退)

2017-02-18  本文已影响2839人  MoonBall

以下内容仅仅是个人经过测试后的猜测!!如果知道官方的定义的,请再评论区指条明路~

iframe

把 iframe 考虑成浏览器新开的 tab 页,是比较合适的~

嵌入 iframe 的页面

假设页面上只嵌入了一个 iframe 元素。以下内容顶层网页用 top 表示,嵌入的 iframe 网页用 iframe 表示。

浏览器的后退

浏览器的后退按钮是面向用户的,既作用整个页面,包含 topiframetop 上的 history 和 iframe 上的 history 的 length 是相同的。window.history.length === window.top.history.length

测试及结论

Chrome 上测试

序号 操作 top page iframe page 备注
1 加载页面 11 21
2 iframe 上点击链接修改 iframe 11 22 location.assign 或 pushState
3 iframe 上点击链接修改 iframe 11 23 location.assign 或 pushState
4 top 执行 location.replace 更新 hash 12 23 top 上单页应用更新
5 点击浏览器后退 11 23 步骤 4 替换了步骤 3 产生的历史记录,浏览器认为从步骤 2步骤 4 只有 top 参与了历史改变,所有只有 top 被回退
6 点击浏览器后退 11 21 步骤 2 回退到步骤 1iframe 参与了历史改变,修改 iframe page 到步骤 1 时的状态
7 点击浏览器前进 11 22 步骤 1 前进到步骤 2iframe 参与了历史改变,修改 iframe page 到步骤 2 时的状态

Chrome 上结论

Chrome 的 history,不仅利用了每一步 topiframe 的状态,还利用了这一步是由那个 window 引起的。点击回退只会使参与了 history 的那个 window 回到上一步该有的状态,点击前进类似。Firefox 跟 Chrome 类似。

Safari 上测试

序号 操作 top page iframe page 备注
1 加载页面 11 21
2 iframe 上点击链接修改 iframe 步骤 1,11 22 location.assign 或 pushState
3 iframe 上点击链接修改 iframe 步骤 1,11 23 location.assign 或 pushState
4 top 执行 location.replace 更新 hash 12 23 top 上单页应用更新,将 top 最近的一条历史替换了,现在步骤 1 2 3top 历史是 12 了
5 点击浏览器后退 12 22 步骤 4 替换了步骤 1 top 产生的历史记录。此时浏览器后退,top 应为 12;iframe步骤 3 回到步骤 2,应为 22
6 点击浏览器后退 12 21 topiframe 组合
7 点击浏览器前进 12 22 同上

Safari 上结论

在 Safari 上 topiframe 是分开的,然后再根据 history 的形成过程进行组合。
在 Safari 上的结论就相对 Chrome 来说要简单一些,但使用 replace 后整个 history 的逻辑对用户来说可能就难以理解了(如上面例子)。测试中 top 的 page 地址都取至控制台输出 location,有可能与地址栏展示的网址不一致,见下面存在的问题

存在的问题

  1. Safari 上发现存在 location 和地址栏网址不一致的情况。在上面的测试例子中, 步骤 5步骤 7 地址栏显示的还是页面 11 对应的网址,但是控制台打印的 location 确是页面 21 的地址。地址栏的链接应该是分开保存的,上一步是啥就是啥吧,不会被脚本篡改。
  2. 发现多次执行 location.replace 后,不会引起 react-router 的 browserHistory.listen,也不会传新的状态给组件。复现步骤(SPA):1 -> 2 -> 3 -> 执行 replace(2) -> 3 -> 执行 replace(2) 不生效;测试的时候 replace 只修改了 hash。(react-router: "^2.0.0")
上一篇 下一篇

猜你喜欢

热点阅读