单击“后退”按钮时,防止从缓存加载野生动物园


76

单击“后退”按钮时,Safari浏览器加载旧的youtube视频时出现问题。我尝试将onunload =“”(此处提到防止Safari 5中的后退按钮缓存)添加到body标签,但是在这种情况下不起作用。

有什么方法可以防止从某个页面的缓存中加载safari?



@MikaTuupola答案应标记为正确答案。
JulienBérubé2014年

这是不起眼的问题我也遇到过,因为在Safari相同BFCache行为:stackoverflow.com/questions/40727989/...
juanmirocks

就我而言,当我只需要操纵一些类时,本文中的代码就可以了。
巴纳·泰克斯

Answers:


196

您的问题是由后退缓存引起的。当用户离开时应该保存页面的完整状态。当用户使用后退按钮导航时,可以非常快地从缓存中加载页面。这与仅缓存HTML代码的普通缓存不同。

为bfcache加载页面时,onload不会触发事件。相反,您可以检查事件的persisted属性onpageshow。初始页面加载时将其设置为false。从bfcache加载页面时,将其设置为true。

Kludgish解决方案是在从bfcache加载页面时强制重新加载。

window.onpageshow = function(event) {
    if (event.persisted) {
        window.location.reload() 
    }
};

如果您使用的是jQuery,请执行以下操作:

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        window.location.reload() 
    }
});

8
这是我到目前为止找到的唯一可行的解​​决方案,但是它并不完美,因为在重新加载之前仍会短暂显示该页面,并且通过禁用javascript可以轻易阻止该解决方案。是否有人设法找到更完整的解决方案?
卢肯斯

这似乎不适用于Android版Chrome(不测试其他任何移动浏览器,因此限制了我的发言)
Dominique

对于IE 11,我不得不使用window.location = window.location而不是window.location.reload(),原因是我认为我已经迷失了时间。
Paul D. Waite,

要在onpageshow触发之前解决页面可见性的问题,可以使用onbeforeunload事件。在此事件期间,您可以将身体的不透明度更改为0。是的,但是页面将​​短暂可见,但不透明度为0。(window.onbeforeunload =()=> {document.body.opacity = 0;})。这适用于Safari的11
假面Stoykov


9

所有这些答案都有些微不足道。在仅适用于onpageshow解决方案的现代浏览器(Safari)中,

window.onpageshow = function (event) {
    if (event.persisted) {
        window.location.reload();
    }
};

但是在速度较慢的设备上,有时您会在重新加载之前看到一秒钟的先前缓存视图。解决此问题的正确方法是在服务器上响应以下提示正确设置Cache-Control

'Cache-Control', 'no-cache, max-age=0, must-revalidate, no-store'


感谢标头似乎可以工作并且比JS解决方案好得多。
安迪

我将此代码放在HEADER中,现在iPhone上的Safari通过“后退”按钮返回此页面时,确实执行JS和JQuery代码,谢谢!
Al-Noor Ladhani

6

是的,Safari浏览器无法像Firefox和Chrome一样处理后退/前进按钮缓存。尽管有新的iframe.src,但几乎不缓存vimeo或youtube视频等iframe。

我发现了三种解决方法。选择最适合您的情况。在Firefox 53和Safari 10.1上测试过的解决方案

1.检测用户是否使用后退/前进按钮,然后通过替换src重新加载整个页面或仅重新加载缓存的iframe

if (!!window.performance && window.performance.navigation.type === 2) {
            // value 2 means "The page was accessed by navigating into the history"
            console.log('Reloading');
            //window.location.reload(); // reload whole page
            $('iframe').attr('src', function (i, val) { return val; }); // reload only iframes
        }

2.如果页面已缓存,请重新加载整个页面

window.onpageshow = function (event) {
        if (event.persisted) {
            window.location.reload();
        }
    };

3.从历史记录中删除该页面,以便用户无法通过后退/前进按钮再次访问该页面

$(function () {
            //replace() does not keep the originating page in the session history,
            document.location.replace("/Exercises#nocache"); // clear the last entry in the history and redirect to new url
        });

2

您可以使用锚点,并查看文档的位置href的值;

开始于http://acme.co/,在该位置附加一些内容,例如'#b';

因此,现在您的URL是http://acme.co/#b,当有人按下后退按钮时,它返回到http://acme.co,并且时间间隔检查功能会看到缺少我们设置的哈希标签,清除了时间间隔,并加载了带有时间戳记的引用URL对此。

有一些副作用,但我会留给您解决;)

<script>
document.location.hash = "#b";
var referrer = document.referrer;

// setup an interval to watch for the removal of the hash tag
var hashcheck = setInterval(function(){
    if(document.location.hash!="#b") {

    // clear the interval
    clearInterval(hashCheck);

    var ticks = new Date().getTime();
    // load the referring page with a timestamp at the end to avoid caching
    document.location.href.replace(referrer+'?'+ticks);
    }
},100);
</script>

这未经测试,但应以最小的调整工作。


3
有趣的是,唯一仍在工作的解决方案获得了负面评级
daslicht

1

该行为与Safari的后退/前进缓存有关。您可以在相关的Apple文档中了解它:http : //web.archive.org/web/20070612072521/http : //developer.apple.com/internet/safari/faq.html#anchor5

苹果自己的修复建议是在页面上添加一个空的iframe:

<iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
    this frame prevents back forward cache
</iframe>

(先前接受的答案似乎也是有效的,只是想加入文档和其他可能的修复方法)


最好的解决办法,我发现在这里:stackoverflow.com/questions/20899274/...
I_A

0

首先在您的代码中插入字段:

<input id="reloadValue" type="hidden" name="reloadValue" value="" />

然后运行jQuery:

jQuery(document).ready(function()
{
        var d = new Date();
        d = d.getTime();
        if (jQuery('#reloadValue').val().length == 0)
        {
                jQuery('#reloadValue').val(d);
                jQuery('body').show();
        }
        else
        {
                jQuery('#reloadValue').val('');
                location.reload();
        }
});

0

有很多方法可以禁用bfcache。最简单的方法是设置一个“卸载”处理程序。我认为让'unload'和'beforeunload'处理程序禁用bfcache是​​一个巨大的错误,但这就是他们所做的(如果您希望拥有其中一个处理程序仍使bfcache工作,则可以在内部删除beforeunload处理程序beforeunload处理程序)。

window.addEventListener('unload', function() {})

在这里阅读更多:

https://developer.mozilla.org/zh-CN/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching


0

使用3个不同的锚链接到下一页时,我遇到了相同的问题。从下一页返回并选择其他锚点时,链接没有更改。

所以我有

<a href="https://www.example.com/page-name/#house=house1">House 1</a>
<a href="https://www.example.com/page-name/#house=house2">View House 2</a>
<a href="https://www.example.com/page-name/#house=house3">View House 3</a>

变成

<a href="/page-name#house=house1">House 1</a>
<a href="/page-name#house=house2">View House 2</a>
<a href="/page-name#house=house3">View House 3</a>

也用于安全:

// Javascript
window.onpageshow = function(event) {
    if (event.persisted) {
        window.location.reload() 
    }
};

// JQuery
$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        window.location.reload() 
    }
});

在线找到的用于单独卸载,重新加载和重新加载(true)的解决方案均无效。希望这对遇到同样情况的人有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.