使用浏览器后退按钮时如何强制重新加载页面?
Posted
技术标签:
【中文标题】使用浏览器后退按钮时如何强制重新加载页面?【英文标题】:How to force reloading a page when using browser back button? 【发布时间】:2017-08-19 23:11:24 【问题描述】:我需要以某种方式检测用户是否按下了浏览器的后退按钮并使用 jquery 重新加载页面并刷新(重新加载内容和 CSS)。
如何通过 jquery 检测这种行为?
因为现在如果我在浏览器中使用后退按钮,某些元素不会重新加载。但如果我使用网站中的链接,一切都会刷新并正确显示。
重要!
有些人可能误解了我想要的东西。我不想刷新当前页面。我想刷新按下后退按钮后加载的页面。这是我更详细的意思:
-
用户正在访问page1。
在第 1 页上 - 他单击指向第 2 页的链接。
他被重定向到第2页
现在(重要的部分!)他点击浏览器中的后退按钮,因为他想返回第 1 页
他又回到了第 1 页 - 现在第 1 页正在重新加载,并且出现类似“你回来了!”这样的警报
【问题讨论】:
与其破解正常的用户行为,为什么不尝试理解为什么您的代码在页面加载时无法正常工作,而您需要重新加载页面? @LelioFaieta 我更改课程以显示更改。如果用户单击某些内容,则数据库中的值会通过 ajax 发生变化。当 ajax 完成时,css 类 cahnge 例如从on
到 off
。没关系,它保存在数据库中,用户可以正确看到所有内容。现在他点击了其他链接。例如关于我们的页面,对吧?现在,他在关于我们的页面上。 Be 决定返回上一页并单击浏览器中的后退按钮。当他回来时,在他触发 ajax(开/关类)之前,当浏览器显示页面时,他会看到页面上的变化(可能是一些浏览器缓存)
您在使用 get 还是 post 进行 Ajax 调用?
@LelioFaieta part2 .. 我也使用数据属性,它没有效果。如果重新加载页面,一切都会很棒。如果我在该页面上按 F5,则会显示他通过 ajax 更改的值。我认为这是一些与浏览器相关的问题,当 css/html 部分没有完全重新加载时。仅在按 f5 后才会重新加载
@LelioFaieta $.ajax( url: url, method: 'post', processData: false, contentType: false, cache: false, dataType: 'json', data: formData, )
你认为这可能是通过ajax 实现的吗?如果是这样就好了。
【参考方案1】:
您可以使用pageshow
事件来处理浏览器通过历史遍历导航到您的页面的情况:
window.addEventListener( "pageshow", function ( event )
var historyTraversal = event.persisted ||
( typeof window.performance != "undefined" &&
window.performance.navigation.type === 2 );
if ( historyTraversal )
// Handle page restore.
window.location.reload();
);
请注意,也可能涉及 HTTP 缓存。您需要在服务器上设置适当的与缓存相关的 HTTP 标头,以仅缓存那些需要缓存的资源。您还可以强制重新加载以指示浏览器忽略 HTTP 缓存:window.location.reload( true )
。但我认为这不是最好的解决方案。
更多信息请查看:
Working with BFCacheMDN 上的文章 WebKit Page Cache II – The unload Event 布雷迪·艾德森 pageshow MDN 上的事件参考 Ajax, back button and DOM updates问题 javascript - bfcache/pageshow event - event.persisted always set to false?问题【讨论】:
你能帮助用户 Dhiraj 他在正确的轨道上,但它重新加载了两次。顺便说一句,我试过window.addEventListener( "unload", function() );
,但它什么也没做,后退按钮和以前一样工作,没有任何改变;(
如何卸载 BFCache?你能用更具体的信息更新你的代码吗?这条线window.addEventListener( "unload", function() );
不起作用。完成了吗?
Chrome 历史遍历有点混乱。请尝试pageshow
解决方案。
我仍然看到双重加载;(一旦默认 Firefox(显示旧页面;可能来自浏览器缓存?)然后脚本再次触发。脚本将重新加载到实际阶段,但我仍然看到旧状态一秒钟左右;(我有代码在$(document).ready( function() /* code here */ );
window.performance.navigation
已弃用。检查我使用的导航类型window.performance.getEntriesByType("navigation")[0].type === "back_forward"
【参考方案2】:
这篇文章发布已经有一段时间了,但如果您不需要支持旧浏览器,我找到了一个更优雅的解决方案。
你可以检查一下
performance.navigation.type
包含浏览器支持的文档在这里:https://developer.mozilla.org/en-US/docs/Web/API/Performance/navigation
所以要查看页面是否是从历史记录中加载的,你可以这样做
if(performance.navigation.type == 2)
location.reload(true);
2
表示该页面是通过导航到历史记录来访问的。其他可能性是-
0:
通过链接、书签、表单提交或脚本访问该页面,或者在地址栏中键入 URL。
1:
该页面是通过单击“重新加载”按钮或通过 Location.reload() 方法访问的。
255:
任何其他方式
这里有详细介绍:https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigation
注意 Performance.navigation.type 现在已弃用,取而代之的是返回 'navigate' / 'reload' / 'back_forward' / 'prerender' 的 PerformanceNavigationTiming.type: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type
【讨论】:
这项检查对我有用。 2 到底是什么意思? 这就像一个魅力..我把它放在最顶部的区域..并且页面正在重新加载而没有加载任何其他脚本。 这就像一个魅力。很棒的发现......它非常快速和可靠,不像其他答案那样慢。 TY 这个适用于 chrome 浏览器,但不适用于 firefox 已弃用(请参阅w3c.github.io/navigation-timing/#obsolete)。【参考方案3】:只需使用 jquery :
jQuery( document ).ready(function( $ )
//Use this inside your document ready jQuery
$(window).on('popstate', function()
location.reload(true);
);
);
当使用 ajax 也单击后退或前进按钮时,上述内容将 100% 工作。
如果没有,那么脚本的不同部分肯定有错误配置。
例如,如果使用类似上一篇文章中的示例window.history.pushState('', null, './');
,它可能不会重新加载
所以当你使用history.pushState();
确保正确使用它。
在大多数情况下您只需要建议:
history.pushState(url, '', url);
没有 window.history... 并确保定义了 url。
希望对您有所帮助..
【讨论】:
这在 IE 中不起作用。 developer.microsoft.com/en-us/microsoft-edge/platform/issues/… @RitchieD - 到目前为止,这在 Windows 10 上的 IE11 中运行良好。注意:我没有使用 EDGE。 只是不喜欢“只使用 jQuery”的答案,抱歉 我会从重新加载中删除“true”以使用 HTTP 缓存。在大多数情况下,没有必要重新加载资产。【参考方案4】:由于performance.navigation
现已弃用,您可以试试这个:
var perfEntries = performance.getEntriesByType("navigation");
if (perfEntries[0].type === "back_forward")
location.reload(true);
【讨论】:
这是最新的答案 此代码需要与上面 Leonid 回答中的代码结合使用。 这对我来说很好用。我在最新的 Chrome、Firefox、IE 和 Edge 中进行了测试。没有在 Mac 上检查 Safari。 有人用 ios 测试过吗?我用 performance.getEntriesByType("navigation") 方法替换了旧的 performance.navigation.type 方法,我页面上的所有 JS 都停止在 iOS 上运行。 developer.mozilla.org/en-US/docs/Web/API/… 表示它还不能在 Safari 或 iOS 上运行...【参考方案5】:您应该使用隐藏输入作为刷新指示器,其值为“no”:
<input type="hidden" id="refresh" value="no">
现在使用 jQuery,你可以检查它的值:
$(document).ready(function(e)
var $input = $('#refresh');
$input.val() == 'yes' ? location.reload(true) : $input.val('yes');
);
当您单击返回按钮时,隐藏字段中的值将保持与您最初离开页面时相同的值。
因此,当您第一次加载页面时,输入的值为“否”。当您返回页面时,它会显示“是”并且您的 JavaScript 代码将触发刷新。
【讨论】:
它不起作用。我尝试过 Firefox 和 Chrome,但都无法正常工作。 请检查我更新的问题,也许你和其他人误解了我。现在更清楚了,我想要完成什么。谢谢。 是的,我确实误解了,感谢您详细更新问题。 现在可以了。但是它重新加载了 2 次,看起来有点奇怪。第一次重新加载。什么都没有——这可能是默认的浏览器行为。第二次重新加载时 - 通过您的脚本 - 值会按原样刷新,但看起来很糟糕,因为它会重新加载两次。任何想法如何改进它,所以重新加载看起来更好或只重新加载一次?它在 Chrome 中看起来比在 Firefox 中更好,重新加载速度更快,但我仍然看到原始的返回状态(一秒或半秒)并且脚本重新加载只是在那之后。 有什么新想法可以解决“双重负载”吗?【参考方案6】:解决我的问题的另一种方法是禁用页面的缓存。这使得浏览器从服务器获取页面而不是使用缓存版本:
Response.AppendHeader("Cache-Control","no-cache, no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "0");
【讨论】:
最佳解决方案,但这是我使用的版本。Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetMaxAge(TimeSpan.Zero); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); Response.Cache.SetNoStore();
这看起来像一个服务器端命令。这是用什么语言写的?【参考方案7】:
目前,如果用户单击后退按钮,这是重新加载页面的最新方式。
const [entry] = performance.getEntriesByType("navigation");
// Show it in a nice table in the developer console
console.table(entry.toJSON());
if (entry["type"] === "back_forward")
location.reload();
来源见here
【讨论】:
有人用 iOS 测试过吗?我用 performance.getEntriesByType("navigation") 方法替换了旧的 performance.navigation.type 方法,我页面上的所有 JS 停止在 iOS 上工作。 developer.mozilla.org/en-US/docs/Web/API/… 表示它还不能在 Safari 或 iOS 上运行...【参考方案8】:重新加载很容易。你应该使用:
location.reload(true);
检测回来是:
window.history.pushState('', null, './');
$(window).on('popstate', function()
location.reload(true);
);
【讨论】:
不工作;(我试过alert('test');
而不是location.reload(true);
但仍然没有。我试过firefox和chrome但没有。我试过里面的文件准备好了,外面,但没有任何效果。如果我尝试了简单的 alert() 或任何有效的 jquery 代码。我的页面上有很多 jquery 代码并且它有效。
我已经编辑了答案,尝试新的解决方案。事情是你需要之前推送状态,否则你不会得到 popstate 事件。
你可能误解了我想要的。我已经用更详细的描述更新了我的问题。请有时间再检查一下,谢谢。【参考方案9】:
我遇到了同样的问题,后退按钮会更新位置字段中显示的 url,但页面内容没有改变。
正如其他人所指出的,可以通过捕获“pageshow”事件来检测 document.location 的变化是由后退按钮还是其他原因引起的。
但我的问题是,当我单击后退按钮时,“pageshow”根本没有触发。唯一发生的事情是位置字段中的 url 发生了变化(就像它应该发生的那样),但页面内容没有改变。为什么?
我从https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event 中找到了理解是什么原因的关键。
它说'pageshow' - 事件是由“从同一窗口或选项卡中的另一个页面导航到页面”或“使用浏览器的前进或后退按钮返回页面”引起的
这让我问:“我真的要返回页面吗?”。 “什么标识页面?”。如果我的后退按钮不是“返回页面”,那么当然“显示页面”根本不会触发。那么我真的是“回到一个页面”吗?还是我可能一直停留在同一个“页面”上?什么是“页面”?如何识别页面?通过网址?
原来我点击后退按钮并没有“更改页面”。它只是改变了我网址中的 HASH(# + 的东西)。当 URL 中唯一变化的是哈希值时,似乎浏览器不会将其视为不同的页面。
所以我修改了在单击按钮时操纵我的网址的代码。除了更改散列之外,我还添加了一个查询参数,我为其提供了与散列相同的值,但没有“#”。所以我的新网址看起来像:
/someUrl?id=something#something
现在,我的应用程序认为是“不同页面”的每个页面的查询字符串参数“id”都有不同的值。就浏览器而言,它们是不同的“页面”。这解决了问题。 'Pageshow' - 事件开始触发和后退按钮工作。
【讨论】:
【参考方案10】:适用于大多数浏览器的 JS 解决方案
此页面上的许多其他方法都不适用于我,可能是因为"bfcache" 正在阻止用户导航回页面时发生任何事情。但是,我发现在大多数浏览器中注册window.onbeforeunload
处理程序对我有用,我相信它可以工作,因为它implicitly invalidates the "bfcache"。代码如下:
window.onbeforeunload = function()
window.location.reload(true);
除了“返回”按钮导航之外,此事件可能会在其他情况下触发,但我的情况并不重要。我于 2021 年 8 月在以下平台上使用列出的浏览器的最新版本对此进行了测试:
Linux:适用于 Chrome 和 Firefox。 android:适用于 Chrome、Firefox 和 Opera。 OS X:适用于 Chrome 和 Safari。 iOS:在 Safari 中不起作用。就我而言,我并不真正关心移动设备。我确实关心 IE,但无法访问 IE,所以我无法对其进行测试。 如果有人在 IE 上尝试此操作并且可以在 cmets 中报告结果,那将很有帮助。
修复 iOS Safari 的服务器端响应标头
我发现如果我使用Cache-Control
response header 使浏览器缓存无效,iOS Safari 也可以工作。 IE。发送
Cache-Control: no-store, must-revalidate
修复了 iOS Safari。如何在各种平台上设置Cache-Control
响应头,请参见this SO answer。
【讨论】:
【参考方案11】:在您的 html 头文件中使用以下元标记,这对我有用。
<meta http-equiv="Pragma" content="no-cache">
【讨论】:
返回时不会重新加载页面,这是 OP 请求的【参考方案12】:这在 11 月 21 日适用于最新的 Firefox 和 Chrome。
window.addEventListener( "pageshow", function ( event )
var perfEntries = performance.getEntriesByType("navigation");
if (perfEntries[0].type === "back_forward")
location.reload();
);
【讨论】:
【参考方案13】:在 Chrome 96 中 perfEntries[0].type 是“重新加载”,当您使用后退按钮时
【讨论】:
【参考方案14】:我尝试了之前答案中的所有解决方案。没有人工作。
最后我找到了这个解决方案,它确实有效:
(function ()
window.onpageshow = function(event)
if (event.persisted)
window.location.reload();
;
)();
【讨论】:
【参考方案15】:我找到了最好的答案,它对我来说非常有效
只需在链接中使用这个简单的脚本
<A HREF="javascript:history.go(0)">next page</A>
或按钮点击事件
<INPUT TYPE="button" onClick="history.go(0)" VALUE="next page">
当你使用这个时,你先刷新你的页面,然后转到下一页, 当您返回时,它将具有上次刷新的状态。
我在 CAS 登录中使用了它,并给了我想要的东西。 希望对您有所帮助.......
详情来自here
【讨论】:
这对我不起作用。 “0”代表什么? 这不是在回答“使用浏览器后退按钮时如何强制重新加载页面?”的问题以上是关于使用浏览器后退按钮时如何强制重新加载页面?的主要内容,如果未能解决你的问题,请参考以下文章