Reputation: 5573
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?
Upvotes: 104
Views: 110444
Reputation: 1219
Other solutions should work otherwise in a authentic way you can use below snippet.
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
if(!navigator.userAgent.includes('Chrome') && navigator.userAgent.includes('Safari')){
window.location.reload();
}
}
});
Upvotes: 0
Reputation: 2131
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 source.
I found three ways to handle this. Choose the best for your case. Solutions tested on Firefox 53 and Safari 10.1
Detect if user is using the back/foreward button, then reload whole page or reload only the cached iFrames by replacing the source:
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
}
Reload whole page if page is cached:
window.onpageshow = function (event) {
if (event.persisted) {
window.location.reload();
}
};
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
});
Upvotes: 7
Reputation: 44609
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:
Safari's Back/Forward cache (the cache pulled from when a visitor presses the Back or Forward browser buttons) can also be thwarted by insuring that your page contains a frame. Frame-based pages are never stored in the back / forward cache and you can insure your non-frame based page behaves similarly by adding the invisible iframe below.
<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)
Upvotes: 2
Reputation: 60875
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 and still make the bfcache work, you can remove the beforeunload handler inside the beforeunload handler).
window.addEventListener('unload', function() {})
Read more here:
https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching
Upvotes: 0
Reputation: 990
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.
Upvotes: 3
Reputation: 179
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'
Upvotes: 17
Reputation: 479
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();
}
});
Upvotes: 0
Reputation: 20387
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()
}
});
Upvotes: 242
Reputation: 1143
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.
Upvotes: 2