Ajax,后退按钮和DOM更新

2022-08-30 05:23:08

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

它在stackoverflow,reddit和许多其他流行网站上以这种方式工作。(尝试向此问题添加测试评论,然后导航到其他页面并点击后退按钮返回 - 您的评论将“消失”)

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

不一致从何而来?


答案 1

一个答案是:除其他事项外,卸载事件会导致后退/前进缓存失效

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

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

jQuery会自动将卸载事件附加到窗口,因此不幸的是,使用jQuery将使您的页面失去存储在bfcache中以进行DOM保留和快速后退/前进的资格。[更新:此问题已在jQuery 1.4中修复,因此仅适用于IE]


答案 2

我一直在努力让Chrome像Safari一样表现,我发现唯一可行的方法就是在标题中设置。这将强制浏览器在用户按下后退按钮时从服务器重新获取页面。不理想,但比显示过时的页面更好。Cache-control: no-store