How to prevent reloading of web page from cache while using mobile safari browser?

9k views Asked by At

Mobile Safari uses a special caching mechanism Page Cache (here) which basically keeps the current page alive but hibernated when we navigate to another page. This way, it can immediately display the previous page in its latest state when user presses back button.

This is useful for navigation and browsing web but for special cases this becomes annoying as you may need to get a fresh copy of the page each time user navigates to that page. (in my case I have to pages: login and main page).

I am totally aware that nothing prevents user from opening multiple tabs of the same application. I not concerned about that.

The cross browser solution for preventing page from being cached does not help as Safari is keeping the page open but invisible and suspended.

The window.onpageshow and handling event.persisted does not help as it seems that the browser does not execute onpageshow event for some reasons the second time (when you press back button).

Note for those who do not know what onpageshow event is about: Apple discourages using load and unload events because with the concept of page cache those events does not make a clear sense. So, onpageshow is supposed to do what we expect from load event.

2

There are 2 answers

2
Bakhshi On BEST ANSWER

When user presses back button, you will receive the same document as you had before (the old page which was suspended). So if you handle onpagehide event and do some modification to the page just before navigating to the new page, your changes are kept there.

I tried adding a script block to the body just before navigating:

if (isSafari) {
        window.addEventListener('pagehide', function(e) {
            var $body = $(document.body);
            $body.children().remove();
                $body.append("<script type='text/javascript'>window.location.reload();<\/script>");
        });
    }

this does not work because the script immediately executes where my intention was to execute it when user returns back to the page.

BUT if you postpone your DOM modifications after leaving pagehide callback, (something like this):

if (isSafari) {
        window.addEventListener('pagehide', function(e) {
            var $body = $(document.body);
            $body.children().remove();

            // wait for this callback to finish executing and then...
            setTimeout(function() {
                $body.append("<script type='text/javascript'>window.location.reload();<\/script>");
            });
        });
    }

TADA it works! as soon as user presses back button on the next page, Safari loads the suspended page and executes this new block of script which has not executed before.

0
Ted Naleid On

Another potential solution is to look at the event.persisted flag to determine if it's cached or not:

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