Ajax、后退按钮和 DOM 更新

如果 javascript 修改了页面 A 中的 DOM,用户导航到页面 B,然后点击返回按钮返回到页面 A。所有对页面 A 的 DOM 的修改都会丢失,用户会看到最初从服务器检索到的版本。

它在 stackoverflow、 reddit 和许多其他流行网站上都是这样工作的。(尝试添加测试评论到这个问题,然后导航到不同的页面,按回车按钮回来-您的评论将是“消失”)

这是有道理的,然而一些网站(apple.com,basecampq.com 等)却以某种方式迫使浏览器为用户提供页面的最新状态。(转到 http://www.apple.com/ca/search/?q=ipod,点击顶部的下载链接,然后点击后退按钮-所有的 DOM 更新将被保留)

where is the inconsistency coming from?

33973 次浏览

您正在寻找的是某种类型的 URL 散列管理。Url 中的 # 仅用于客户端。

当您使用 JS 更改 back 的状态时,然后更新 url 的 # 中的数据。

还可以添加某种类型的轮询,用于监视散列是否已更改,并根据散列中的新数据加载页面的状态。

看看这个:

Http://ajaxpatterns.org/unique_urls

Facebook 通过修改 Ajax 请求 URL 中的散列标识符来记住页面状态。这些更改记录在浏览器历史记录中,因此当用户单击“后退”按钮时,散列就会变成以前的样子。因此,这意味着您将需要一些 Javascript 来监视 has 标识符,并在浏览器更改它时作出反应。Andreas Blixt 有一个散列监视脚本可用.

Using the URL hash/fragment identifier is a pretty common way to hook/remember state in a web application that relies on Ajax and DOM updates.

查看 非常简单的历史项目以获得一些想法。监视 URL 对散列的更改是可能的,rsh 可以做到这一点,同时考虑到浏览器的差异。

这与 hash (#)符号无关。

如果你想检查苹果的 HTTP 头,它只是简单地缓存页面。

答案之一是: 卸载事件导致后退/前进缓存失效

有些浏览器将整个网页的当前状态存储在所谓的“ bfcache”或“ page cache”中。这允许他们在通过后退和前进按钮导航时非常快速地重新呈现页面,并保留 DOM 和所有 JavaScript 变量的状态。但是,当页面包含 onunload 事件时,这些事件可能会使页面进入非功能状态,因此页面不存储在 bfcache 中,必须重新加载(但可以从标准缓存加载)并从头重新呈现,包括运行所有 onload 处理程序。当通过 bfcache 返回到页面时,DOM 保持其以前的状态,不需要触发 onload 处理程序(因为页面已经加载)。

请注意,与 Cache-Control 和其他 HTTP 头相比,bfcache 的行为不同于标准浏览器缓存。在许多情况下,浏览器将在 bfcache 中缓存页面,即使它不会以其他方式将页面存储在标准缓存中。

JQuery 会自动将卸载事件附加到窗口,因此很不幸,使用 jQuery 会使您的页面失去存储在 bfcache 中的资格,无法保存 DOM 和快速返回/转发 。[更新: jQuery 1.4已经修复了这个问题,所以它只适用于 IE ]

我一直试图让 Chrome 像 Safari 那样运行,我发现唯一可行的方法就是在标题中设置 Cache-control: no-store。这会迫使浏览器在用户按下后退按钮时从服务器重新获取页面。不是很理想,但总比显示过时的页面要好。

对于任何使用 Rails遇到问题的人来说,这个问题不是 bfcache (我以为是) ,而是 turbolinks gem。给你是如何移除它。

Hopefully this'll save you some time and banging your head against the wall.