html - 如何将 AJAXy 页面更新与后退按钮混合在一起,以便在用户返回时更新仍然存在?

标签 html ajax browser back-button

我有一个用户可以修改的页面。所有修改都使用 JQuery 执行,并发送到服务器,以便完全重新加载也会生成修改后的页面。

这在 Windows 上的 Firefox 11/Chrome 中运行良好:即使用户导航到其他地方然后使用“返回”按钮,他们也会获得包含最新编辑的页面。

但是,如果我现在将 Google map 嵌入到页面中,后退按钮将停止工作:它会将用户带到页面上的所有编辑之前的状态。除了在浏览器的缓存中,这个页面甚至不再存在,但它被显示出来。

我整理了一个 简单的测试用例 here这表明这种行为。

是什么赋予了?我怎样才能解决这个问题?完美的解决方案只是允许浏览器返回而不像通常那样重新加载页面。

附言显然,“工作”示例实际上也不适用于 OSX 上的 Chrome。如何解决浏览器坚持返回页面的陈旧版本的问题?

错误报告 描述此行为:Firefox

赏金 :Windows 上的 Firefox 和 Chrome 表现出这两种行为(在一种情况下返回到修改后的 DOM,但在另一种情况下未修改)。是否有描述浏览器应该做什么的规范?是否有提交的错误以一种或另一种方式改变这种情况?这个问题有一个我可以用谷歌搜索的通用名称吗?

我正在考虑一种解决方案,即通过 JavaScript 更新隐藏元素,然后检查更新是否仍然存在。如果是这样,“返回”按钮将恢复最新的 DOM,无需执行任何其他操作。如果没有,浏览器会恢复过时的 DOM,我可以强制重新加载页面,尽管如此令人不快。也欢迎对此方法提出任何意见。

备注 :真正的网站有更多的可编辑控件,其中之一是自由格式的文本区域。即使用户刚刚添加了几段文本,我也希望所提出的解决方案能够工作。那种东西不能加在#后面的URL后面, 例如。

最佳答案

将 Google map 嵌入页面会禁用 bfcache(我将使用 mozilla 术语表示缺乏标准缓存),因为 map 页面加载在 <iframe> 中。使用 unload听众。

在 Firefox 中快速返回导航页面没有被缓存的可能原因列在 MDN 上:Using Firefox 1.5 caching .您的问题被列为“顶级页面包含不可缓存的框架”,这令人困惑,我稍后会尝试澄清。 (其他浏览器可能使用类似的启发式方法,因为开发这些规则是为了避免破坏现有内容 - 另请参阅 this answer ,它有一些链接。)

解决这个问题的正确方法是与谷歌的某个人交 friend ,然后唠叨他们,直到他们删除 onunload至少来自 map 的嵌入页面的听众。

一般来说,您永远不应该依赖 bfcache 对特定页面工作或不工作。这只是对常见情况的优化。由于它是一种优化,因此可以禁用它,例如当系统内存不足时。如果用户在返回之前重新启动浏览器,或者关闭选项卡并选择“撤消关闭选项卡”,它也将不起作用,如您在错误中所述。

您应该从 JS 恢复页面的状态或将页面标记为不可缓存(使用 HTTP header )。当然,前者会带来更好的用户体验。 @Adam Gent 的建议看起来是正确的,我必须检查他所指的 Firefox 问题。

bfcache 以这种方式工作的原因是:

  • 如果浏览器运行 onunload 处理程序,然后通过 bfcache 恢复页面,页面可能会损坏,因为脚本经常删除 onunload 处理程序中的事件监听器(为了“清理”,除了旧的 IE 版本之外,这不是真正必要的)
  • 如果浏览器停止运行 onunload页面中的处理程序基于用户可能返回到页面并且他们想要缓存它,作者会提示。
  • 如果无法缓存 iframe 中的页面,则恢复缓存的外部页面并重新加载内部页面有时会破坏它们(例如,如果两个页面是同域的,则外部页面可以保存对框架中对象的引用,这将赢得'重新加载内部框架后无效)。因此,如果 iframe 未缓存,则父页面也未缓存。

  • 当您点击“返回”时,页面仍然从(磁盘)缓存加载的原因可能是您指定了可以缓存发送到浏览器的内容。浏览器无法知道您在更新服务器上的页面的同时对其进行 DOM 更改。

    希望这可以帮助。

    [编辑]我将详细说明上面的“将页面标记为不可缓存”的想法。为了让 Web 浏览器缓存为您服务而不是对您不利,重要的是要记住 HTTP 是一种用于检索资源的协议(protocol)。例如,由 URL http://bbb.akshell.com/broken 标识的 HTML 页面是一种资源。当您通过 HTTP 提供资源时,您指定浏览器的资源副本的有效时间(即匹配服务器上资源的规范版本)。

    当资源是一个 HTML 页面时,如在您的测试用例中,用户选择的项目以特殊方式标记,资源可能随时更改(每次用户更改选择时)。这意味着提供此资源时的诚实 HTTP 响应将是“不缓存,可能随时更改”。浏览器会在每次需要加载页面时从服务器重新加载页面——这是正确的行为,但代价是用户的速度变慢。

    另一种适用于在多个页内选项卡之间切换的方法是将每个选择与其自己的 URL 相关联。具有两个选项卡的页面将对应于两个资源(和两个 URL)——每个选项卡一个。这两种资源都可以被浏览器 (HTTP-) 缓存。无需通过 pushState 往返服务器即可实现更改 URL 和页面内容。

    另一种似乎更适用于您的情况的方法,即您将用户的输入保存在服务器上:将应用程序 UI 和用户的数据分离到不同的资源中(即使用 JS 的静态(HTTP-)可缓存 HTML 页面,加载用户来自单独的不可缓存 URL 的数据)。请求用户数据并在加载时更新 UI。[/edit]

    关于html - 如何将 AJAXy 页面更新与后退按钮混合在一起,以便在用户返回时更新仍然存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9775738/

    相关文章:

    javascript - 在 html 页面上一次播放一个视频

    javascript - Google Maps Javascript API 忽略输入字段的 CSS

    Css - 图放置

    javascript - AJAX 中的 onreadystatechange 不起作用

    c# - 使用 invokescript 将 bool 值从 javascript 传递到 C#

    php - 如何在 PHP 中的 MySQL 中从单选按钮插入值

    javascript - 验证表单,检查用户是否存在,注册他们。全部使用 Ajax

    javascript - jQuery 中变量的 riptscope

    android - 从 Android WebView 启动下载链接后如何自动关闭浏览器?

    在所有浏览器中模糊的 SVG 矩形