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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8788802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:30:51  来源:igfitidea点击:

Prevent safari loading from cache when back button is clicked

javascriptcachingsafariback-button

提问by Mark Steggles

Got an issue with safari loading old youtube videos when back button is clicked. I have tried adding onunload="" (mentioned here Preventing cache on back-button in Safari 5) to the body tag but it doesn't work in this case.

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

Is there any way to prevent safari loading from cache on a certain page?

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

回答by Mika Tuupola

Your problem is caused by back-forward cache. It is supposed to save complete state of page when user navigates away. When user navigates back with back button page can be loaded from cache very quickly. This is different from normal cache which only caches HTML code.

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

When page is loaded for bfcache onloadevent wont be triggered. Instead you can check the persistedproperty of the onpageshowevent. It is set to false on initial page load. When page is loaded from bfcache it is set to true.

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

Kludgish solution is to force a reload when page is loaded from bfcache.

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

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

If you are using jQuery then do:

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

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

回答by waj-er-rr

All of those answer are a bit of the hack. In modern browsers (safari) only on onpageshowsolution work,

所有这些答案都有点小技巧。在现代浏览器 (safari) 中仅用于onpageshow解决方案工作,

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

but on slow devices sometimes you will see for a split second previous cached view before it will be reloaded. Proper way to deal with this problem is to set properly Cache-Control on the server response to one bellow

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

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

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

回答by Javan R.

Yes the Safari browser does not handle back/foreward button cache the same like Firefox and Chrome does. Specially iframes like vimeo or youtube videos are cached hardly although there is a new iframe.src.

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

I found three ways to handle this. Choose the best for your case. Solutions tested on Firefox 53 and Safari 10.1

我找到了三种方法来处理这个问题。选择最适合您的情况。在 Firefox 53 和 Safari 10.1 上测试的解决方案

1. Detect if user is using the back/foreward button, then reload whole page or reload only the cached iframes by replacing the src

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. reload whole page if page is cached

2.如果页面被缓存,则重新加载整个页面

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

3. remove the page from history so users can't visit the page again by back/forward buttons

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
        });

回答by L422Y

You can use an anchor, and watch the value of the document's location href;

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

Start off with http://acme.co/, append something to the location, like '#b';

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

So, now your URL is http://acme.co/#b, when a person hits the back button, it goes back to http://acme.co, and the interval check function sees the lack of the hash tag we set, clears the interval, and loads the referring URL with a time-stamp appended to it.

所以,现在你的 URL 是http://acme.co/#b,当一个人点击后退按钮时,它返回到http://acme.co,间隔检查功能发现我们设置的哈希标签缺失,清除间隔,并加载附加时间戳的引用 URL到它。

There are some side-effects, but I'll leave you to figure those out ;)

有一些副作用,但我会让你自己弄清楚;)

<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>

This is untested but it should work with minimal tweaking.

这是未经测试的,但它应该在最少的调整下工作。

回答by Simon Boudrias

The behavior is related to Safari's Back/Forward cache. You can learn about it on the relevant Apple documentation: http://web.archive.org/web/20070612072521/http://developer.apple.com/internet/safari/faq.html#anchor5

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

Apple's own fix suggestion is to add an empty iframe on your page:

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

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

(The previous accepted answer seems valid too, just wanted to chip in documentation and another potential fix)

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

回答by Ivan Laharnar mink.si

First of all insert field in your code:

首先在代码中插入字段:

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

then run jQuery:

然后运行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();
        }
});

回答by B T

There are many ways to disable the bfcache. The easiest one is to set an 'unload' handler. I think it was a huge mistake to make 'unload' and 'beforeunload' handlers disable the bfcache, but that's what they did (if you want to have one of those handlers andstill make the bfcache work, you can remove the beforeunload handler inside the beforeunload handler).

有很多方法可以禁用 bfcache。最简单的方法是设置一个“卸载”处理程序。我认为让 'unload' 和 'beforeunload' 处理程序禁用 bfcache 是一个巨大的错误,但这就是他们所做的(如果你想拥有这些处理程序之一仍然使 bfcache 工作,你可以删除里面的 beforeunload 处理程序beforeunload 处理程序)。

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

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

Read more here:

在此处阅读更多信息:

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

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