Prevent safari loading from cache when back button is clicked

痞子三分冷 提交于 2019-12-27 10:50:07

问题


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.

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


回答1:


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.

When page is loaded for bfcache onload event wont be triggered. Instead you can check the persisted property of the onpageshow event. It is set to false on initial page load. When page is loaded from bfcache it is set to true.

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

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

If you are using jQuery then do:

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



回答2:


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.

I found three ways to handle this. Choose the best for your case. Solutions tested on Firefox 53 and 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

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

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

$(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:


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

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'




回答4:


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

Start off with http://acme.co/, append something to the location, like '#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.

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.




回答5:


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

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

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




回答6:


First of all insert field in your code:

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

then run 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();
        }
});


来源:https://stackoverflow.com/questions/8788802/prevent-safari-loading-from-cache-when-back-button-is-clicked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!