防止单击后退按钮时从缓存加载 Safari

问题描述 投票:0回答:9

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

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

javascript caching safari back-button
9个回答
235
投票

您的问题是由前后缓存引起的。当用户离开时,它应该保存页面的完整状态。当用户使用后退按钮导航回来时,可以非常快速地从缓存加载页面。这与仅缓存 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() 
    }
});

16
投票

所有这些答案都有点破解。在现代浏览器(Safari)中仅在

onpageshow
解决方案上工作,

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

但在慢速设备上,有时您会在重新加载之前看到一瞬间之前的缓存视图。处理这个问题的正确方法是在服务器响应上正确设置缓存控制,如下所示

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


7
投票

是的,Safari 浏览器不像 Firefox 和 Chrome 那样处理后退/前进按钮缓存。特别是像 vimeo 或 youtube 视频这样的 iframe 几乎不会被缓存,尽管有一个新的 iframe.src。

我找到了三种方法来处理这个问题。选择最适合您的情况。 在 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
        });

3
投票

我在使用 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)的解决方案都没有单独起作用。希望这可以帮助有相同情况的人。


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>

这尚未经过测试,但只需进行最少的调整即可工作。


1
投票

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

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

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

(之前接受的答案似乎也有效,只是想加入文档和另一个潜在的修复)


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 是一个巨大的错误,但这就是他们所做的(如果您想让这些处理程序之一and仍然使 bfcache 工作,您可以删除 beforeunload beforeunload 处理程序内的处理程序)。

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

在这里阅读更多内容:

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


0
投票

上述解决方案应该可以正常工作,否则您可以使用下面的代码片段。

          window.addEventListener('pageshow', (event) => {
            if (event.persisted) {
              if(!navigator.userAgent.includes('Chrome') && navigator.userAgent.includes('Safari')){
                window.location.reload();
              }
            }
          });
© www.soinside.com 2019 - 2024. All rights reserved.