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

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

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

但是,如果我现在将Google地图嵌入到页面中,则“后退”按钮将停止工作:它会将用户带到页面之前的所有编辑状态.除了在浏览器的缓存中,此页面甚至不再存在,但它仍会显示.

我已经整理了一个显示此行为的简单测试用例here.

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

附:显然,“工作”示例实际上在OSX上的Chrome中也不起作用.我如何解决浏览器坚持回到页面陈旧版本的问题?

描述此行为的错误报告:Firefox

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

我正在考虑一种解决方案,我通过JavaScript更新隐藏元素,然后检查更新是否仍然存在.如果是这样,“后退”按钮恢复了最新的DOM,并且不需要做任何其他事情.如果没有,浏览器恢复过时的DOM,我可以强制页面重新加载,因为这是令人不快的.对这种方法的任何评论也是受欢迎的.

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

解决方法

将Google地图嵌入页面会禁用bfcache(我将使用mozilla术语缺少标准术语)因为地图页面加载了< iframe>使用卸载侦听器.

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

解决这个问题的正确方法是与Google的某个人交朋友,然后唠叨他们,直到他们至少从地图的嵌入页面移除onunload监听器.

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

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

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

>如果浏览器运行onunload处理程序,然后通过bfcache恢复页面,页面可能会被破坏,因为脚本经常删除onunload处理程序中的事件侦听器(“清理”,除了旧的IE版本之外,这不是必需的) )
>如果浏览器停止在页面中运行onunload处理程序,因为用户可能会返回页面并且他们想要缓存它,作者会抱怨.
>如果iframe中的页面无法缓存,则恢复缓存的外页并重新加载内部页面有时会破坏它们(例如,如果两个页面都是同一个域,则外部页面可以保存对框架中对象的引用,在重新加载内部框架后将无效).因此,如果没有缓存iframe,父页面也不会.

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

希望这可以帮助.

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

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

另一种适用于在多个页内标签之间切换的方法是将每个选择与其自己的URL相关联.具有两个选项卡的页面将对应于两个资源(和两个URL) – 每个选项卡一个.两种资源都可以由浏览器缓存(HTTP-).更改URL和页面内容可以在没有通过pushState到服务器的往返的情况下实现.

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

相关文章

vue阻止冒泡事件 阻止点击事件的执行 &lt;div @click=&a...
尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用...
后台我拿的数据是这样的格式: [ {id:1 , parentId: 0, name:...
JAVA下载文件防重复点击,防止多次下载请求,Cookie方式快速简...
Mip是什么意思以及作用有哪些