使用浏览器后退按钮时如何强制重新加载页面?

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 例如从 onoff。没关系,它保存在数据库中,用户可以正确看到所有内容。现在他点击了其他链接。例如关于我们的页面,对吧?现在,他在关于我们的页面上。 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”代表什么? 这不是在回答“使用浏览器后退按钮时如何强制重新加载页面?”的问题

以上是关于使用浏览器后退按钮时如何强制重新加载页面?的主要内容,如果未能解决你的问题,请参考以下文章

按下后退按钮时强制重新加载/刷新

如何在 jQuery 中强制页面刷新或重新加载?

浏览器后退按钮显示缓存中的页面?

如何阻止 chrome 缓存

当用户再次导航返回和前进时强制刷新/重新加载

通过浏览器后退按钮到达时重新加载网站