简体   繁体   中英

How can I force a web browser to reload the document when it is viewed by clicking the Back button?

I have seen related questions on StackOverflow, but none of the suggestions are working for me. I need browsers to reload a page from the server every time it is displayed, including if the user got there by pressing the Back button. It seems like browsers obey caching rules for everything except the base document. This happens in current versions of Safari and Firefox (as of Dec 2013), verified by packet capture.

The pages in my application are used to edit a database record. At the top of the source files are a couple lines of PHP to store a lock indicating that the record is being edited. Other users cannot edit the same record while the lock exists. The pages have a window unload handler that uses AJAX in non-async mode to release the lock. (There's more to the locking mechanism, but those are the relevant pieces.) When the user returns to the page via Back button, the server-side code is never executed.

I have tried including a header:

Cache-Control: no-cache, must-revalidate

Safari's inspector shows the header was received and processed, but it still does not re-retrieve the page.

I have tried setting a handler to check whether the page's state was maintained:

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

The if condition never matches: event.persisted is always false.

The annoying part is that this appears to be technically correct. According to the relevant part of the HTML5 spec , since the page registers an unload listener the browser should never try to maintain page state. And it doesn't! When the user presses the back button, the browser is "replaying" the entire page load sequence, including the ready event. It repeats any AJAX calls where the prior results were not cached. The only thing it refuses to actually reload from the server is the main document itself.

How do I get it to reload the main document?

Quick answer:

No you can't... the Back button is even more aggressive and different of a cache than the others. Some insight:

Why is Google Chrome going to the server on pushState?

https://github.com/nickhsharp/prefetchNightmare

That said... a GET request (the browser loading it) shouldn't "do" anything to the server... if anything you should do that lock setting part via an AJAX on the page start... the inverse of how you remove it using AJAX on the done part.

The browsers are pretty clear on their reasons for the crazy BACK/FORWARD caches and you're not going to be able to force their hands on this one.

Adding this code to my HTML works just fine for me:

<input id="isOld" type="hidden" />
<script>
    onload = function () {
        var el = document.getElementById('isOld');
        if (el.value) {
            el.value = '';
            location.reload();
        }
        el.value = true;
    };
</script>

The code assigns a value to the hidden input that will remain after the back button is clicked in which case the page is force refreshed.

And here's a stripped down version of the above:

<input id="isOld" type="hidden" />
<script>
    setTimeout(function () {
        var el = document.getElementById('alwaysFetch');
        el.value = el.value ? location.reload() : true;
    }, 0);
</script>

This time we no longer rely on the onload event which might conflict with other code elsewhere.

There is HTML5 has History API https://developer.mozilla.org/en-US/docs/Web/API/History

Perhaps you may try that.

Nick Sharp's answer is correct - you are trying to find a solution to a problem you've created by the way you've built the application. There are some potential solutions: Optimistic locking mostly works - but bind the session id not the user id. Alternatively you could rebuild it modelling it along the lines of a thick client application - where all the interaction is mediated by javascript within a single HTML page load.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM