Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Safari from loading back button cache? [duplicate]

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?

like image 460
Mark Steggles Avatar asked Jan 09 '12 13:01

Mark Steggles


People also ask

How do I reduce the cache in Safari?

Android. Select Menu, then More. Select Settings. Under "Privacy settings", select Clear cache, Clear history, or Clear all cookie data as appropriate, and then OK to accept.

Where does Safari keep cache?

The location of cache files is in your ~/Library/Containers/com. apple. Safari/Data/Library/Caches (earlier versions of macOS: ~/Library/Caches/ ) folder.

Can you clear cache for a specific website Safari?

To delete the site Cache storage of some specific sites from Safari iOS, you need to open the Settings>Safari App>Adavnced> Website Data. Now, in the Website Data, tap on edit and then select the specific sites whose site storage you want to delete and then tap on delete.


6 Answers

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() 
    }
});
like image 114
Mika Tuupola Avatar answered Oct 03 '22 18:10

Mika Tuupola


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'

like image 27
waj-er-rr Avatar answered Oct 03 '22 19:10

waj-er-rr


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
        });
like image 21
Javan R. Avatar answered Oct 03 '22 20:10

Javan R.


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.

like image 31
Larry Williamson Avatar answered Oct 03 '22 19:10

Larry Williamson


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)

like image 21
Simon Boudrias Avatar answered Oct 03 '22 18:10

Simon Boudrias


I had the same issue with using 3 different anchor links to the next page. When coming back from the next page and choosing a different anchor the link did not change.

so I had

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

Changed to

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

Also used for safety:

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

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

None of the solutions found online to unload, reload and reload(true) singularily didn't work. Hope this helps someone with the same situation.

like image 22
user3615851 Avatar answered Oct 03 '22 20:10

user3615851