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

Posted

技术标签:

【中文标题】按下后退按钮时强制重新加载/刷新【英文标题】:Force reload/refresh when pressing the back button 【发布时间】:2012-02-22 17:13:02 【问题描述】:

我会尽力解释这一点。

我有一个应用程序,在我的view 页面中显示了 50 多个项目。用户可以点击单个项目进入update页面更新项目信息。一切正常,除了用户完成更新单个项目信息并点击浏览器上的“返回”按钮到之前的view page。旧的项目信息(更新前)仍然存在。用户必须点击刷新才能看到更新的信息。这还不错,但我希望提供更好的用户体验。有什么想法可以解决这个问题吗?非常感谢。

【问题讨论】:

【参考方案1】:

好吧,您可以在更新页面上提供一个内置的后退按钮,将它们发送到新的页面(如链接 <a href="<?= $_SERVER['HTTP_REFERRER']; ?>">BACK</a> 或在页面上放置一些脚本,以强制它在每次更新时提取数据)页面被点击,无论是新的展示,还是使用了返回按钮。

【讨论】:

我的更新页面上有一个“返回主界面”按钮,但我不能确定用户不会在浏览器中点击返回按钮。此外,我的视图页面中有几种项目类型。我不能简单地添加脚本来强制页面刷新数据库中的数据,因为很难知道用户上次选择的项目类型。 +1虽然。谢谢。【参考方案2】:

您可以在查看页面上发送 HTTP 标头,告诉浏览器该页面无法被缓存。这意味着浏览器每次访问时都需要向服务器请求页面 - 这意味着它始终显示最新信息。

标题需要在任何其他内容之前发送,因此请将以下内容放在视图页面的顶部。

header("Cache-Control: no-cache, must-revalidate");

【讨论】:

感谢 cb1。我试过了,但它仍然显示更新前的信息。这就是我放在视图页面顶部的内容。 ...+1 虽然 这很奇怪@Jerry - 以前每次都对我有用。此外,将header("Pragma: no-cache"); 放在 Cache-Control 标头下方也没有什么坏处 - 是的,将它放在视图页面的顶部是正确的。我认为您在重新测试之前清除了浏览器的缓存? 我确实清除了缓存并尝试了 firefox 和 chrome。我也添加了您的第二个代码,但仍然无法正常工作。不过谢谢。 :( 我和杰瑞有同样的问题 这不适用于后退按钮 - 仅适用于该页面的其他导航操作。【参考方案3】:

我认为您必须使用 JS 才能完成这项工作,因为 php 无法知道用户可以访问哪些浏览器控件...

也许这会有所帮助: http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_javascript

【讨论】:

onbeforeunload 不再受支持! @FranciscoCorralesMorales 你在说this吗?【参考方案4】:

这是我在某些页面中使用的解决方案。将此添加到进行更改的页面。

window.onbeforeunload = function() 
     window.name = "reloader"; 
        

这会在您离开这些页面时触发。如果进行了更改,您也可以触发它。这样它就不会不必要地重新加载需要重新加载的页面。 然后在浏览器“返回”使用后要重新加载的页面上。

if (window.name == "reloader")
      
        window.name = "no";
        reloadPage(); 
      

这将触发您需要重新加载到的页面上的重新加载... 希望这可以帮助 :) 哦,顺便说一句,这是在 js 中。

【讨论】:

不幸的是,这在 Firefox 中不起作用(在 v16.0.1 中测试) Firefox (v16.0.1) 你确定吗?我所有的旧代码仍然有效。我实际上重新检查了。 刚刚用 Chrome 版本“30.0.1599.69 m”测试了这个,它似乎不起作用。【参考方案5】:

“fb-cache”真的很烦人。这是一个简单的 javascript 方法:

window.onpageshow = function(evt) 
    // If persisted then it is in the page cache, force a reload of the page.
    if (evt.persisted) 
        document.body.style.display = "none";
        location.reload();
    
;

在 Safari 6 和 IE10 中测试。

【讨论】:

其实这样可以,但是在ios中它只工作一次,如果你尝试向前点击向后返回,你会注意到这个事件只触发了一次。 @Rantiev 这是用于 iOS 上的 Safari 的吗? 对不起,这是在 2013 年夏天在 Safari 6 和 IE10 上测试的。如果您对此解决方案有疑问并找到替代解决方案或对此解决方案进行调整 - 通过提供它们来帮助他人。我也很乐意用您的任何发现来更新答案。谢谢。【参考方案6】:

我使用 jquery 和 php 脚本来强制重新加载后退按钮。 window.unload 部分仅在 Firefox 中需要。注释掉的超时 1 秒和正文附加部分仅用于说明功能。 window.location.reload(true) 将给出与 window.location.href = window.location.href 相同的结果;

jquery:

<script>
    $(window).unload(function() );


        $.get('h.php',function(data)
            if($.trim(data)=='first')
               // $('body').append(data)
               // setTimeout(function()
               window.location.href = window.location.href;
               // ,1000)
            
            else 
                // $('body').append(data)
            
        );

</script>

h.php:

<?php session_start(); ?>
<?php 
if(!$_SESSION['reloaded'])
    echo 'first';   

    $_SESSION['reloaded']=1;

else 
    echo 'second';
    unset($_SESSION['reloaded']);   

?>

【讨论】:

【参考方案7】:

制作一个隐藏的复选框并使用下面的代码(coffeescript)

window.location.reload()  if $("#refreshCheck")[0].checked
  $("#refreshCheck")[0].checked = true

【讨论】:

【参考方案8】:
 if (window.name == "reloader") 
            window.name = "";
            location.reload();
        

window.onbeforeunload = function() 
                window.name = "reloader"; 
            

在每个页面中添加这两个功能

【讨论】:

【参考方案9】:

我使用这四行 PHP 代码:

// any valid date in the past
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// always modified right now
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
// HTTP/1.1
header("Cache-Control: private, no-store, max-age=0, no-cache, must-revalidate, post-check=0, pre-check=0");
// HTTP/1.0
header("Pragma: no-cache");

关键是使用 Cache-Control 标头的“no-store”子句。

【讨论】:

这对我有用。我认为使用浏览器(通过 PHP)是最安全的选择,尤其是在关闭 JavaScript 的情况下。 这对我来说不适用于 Safari 9,但它确实适用于 Chrome 注:if both post-check and pre-check are specified and set to 0, both are entirely ignored. 以及:If you want to prevent caching, do not include the post-check and pre-check directives. Doing so is completely unnecessary and results in wasted bandwidth and HTTP header processing cycles. 来源:blogs.msdn.microsoft.com/ieinternals/2009/07/20/…【参考方案10】:

这是我使用的解决方案:

<?php
session_start();
if (!$_SESSION['reloaded']) $_SESSION['reloaded'] = time();
else if ($_SESSION['reloaded'] && $_SESSION['reloaded'] == time())  ?> 
<script> 
location.reload(); 
</script> 
<?php  ?>

【讨论】:

【参考方案11】:

以上解决方案都不适合我。 这个简单的解决方案发布在here 工作......

当用户单击返回按钮时,我尝试强制浏览器再次下载页面,但没有任何效果。我似乎现代浏览器有单独的页面缓存,它存储页面的完整状态(包括 JavaScript 生成的 DOM 元素),所以当用户按下后退按钮时,前一页会立即以用户离开的状态显示。如果您想强制浏览器在返回按钮上重新加载页面,请将 onunload="" 添加到您的 (X)html 正文元素中:

&lt;body onunload=""&gt;

这将禁用特殊缓存并在用户按下时强制页面重新加载 返回键。使用前请三思。需要这样的事实 解决方案暗示您的网站导航概念存在缺陷。

【讨论】:

完美。尝试了 10 多种解决方案,但这对我有帮助。【参考方案12】:

幸运的是,我们不必支持 IE10 以下的浏览器,所以如果您愿意或有足够的特权只支持支持 HTML5 的浏览器,那么以下应该可以工作:

/*
 * The following is intentional, to force Firefox to run 
 * this JS snippet after a history invoked back/forward navigation.
 */
window.onunload = function();    

function formatTime(t) 
    return t.getHours() + ':' + t.getMinutes() + ':' + t.getSeconds();


if (window.history.state != null && window.history.state.hasOwnProperty('historic')) 
    if (window.history.state.historic == true) 
        document.body.style.display = 'none';
        console.log('I was here before at ' + formatTime(window.history.state.last_visit));
        window.history.replaceState(historic: false, '');
        window.location.reload();
     else 
        console.log('I was forced to reload, but WELCOME BACK!');
        window.history.replaceState(
            historic  : true,
            last_visit: new Date()
        , '');
    
 else 
    console.log('This is my first visit to ' + window.location.pathname);
    window.history.replaceState(
        historic  : true,
        last_visit: new Date()
    , '');

好吧,下面是没有 cmets 和 flab 的代码:

window.onunload = function();

if (window.history.state != null && window.history.state.hasOwnProperty('historic')) 
    if (window.history.state.historic == true) 
        document.body.style.display = 'none';
        window.history.replaceState(historic: false, '');
        window.location.reload();
     else 
        window.history.replaceState(historic  : true, '');
    
 else 
    window.history.replaceState(historic  : true, '');

把它贴在你的结束 body 标签之前,你会有一个相当干净的解决方案。

这适用于单击后退/前进的任意组合,并且当用户登陆新页面时,不会发生强制重新加载。

在 MDN 上阅读有关 History 对象的更多信息:

MDN - The History Object

MDN - Manupulating the Browser History

【讨论】:

您介意添加标签 吗?因此即使对于经验不足的人也可以实施。【参考方案13】:

在网上找了几天解决办法,终于弄明白了,补充一下:

<script>
 window.onbeforeunload = function()window.location.reload();
</script>

这将像一个魅力 你会感谢我的

此代码将在您访问时重新加载页面。

【讨论】:

这正是我所需要的,谢谢!我尝试了许多其他应该检测通过“后退”按钮访问页面的解决方案,但它们都不起作用。我认为我尝试过的其他方法的问题可能与“bfcache”有关,因为显然设置window.onbeforeunload 隐式地使“bfcache”无效。

以上是关于按下后退按钮时强制重新加载/刷新的主要内容,如果未能解决你的问题,请参考以下文章

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

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

单击 Safari 上的后退按钮时使用 React 挂钩强制页面重新加载

按下后退按钮时防止反应路由器重新加载 API 调用。反应

按下后退按钮时正在重新创建 Listview 片段

后退按钮刷新/重新加载 uipickerview 内容