Bakhshi Bakhshi - 8 days ago 6
iOS Question

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

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.

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.

Comments