简体   繁体   中英

force all page visits to refresh/clear cache after login/logout

My site is constructed entirely of dynamic data, some of which changes based on user authentication. When a user "logs in" to the site, I show their new status with their user name in the page navigation bar. However when they visit a page they visited recently before authenticating (back button, etc), that page's version of the navigation bar will not be refreshed. What are some methods to force a refreshed page to the browser? The inverse is also true: if a user logs out, recent pages will still show authenticated from the cached version.

What technique can I use to always force a browser-side refresh/clear cache on any page on the website?

Thanks.

Nb: server side I am using eXist-db 4.7's login:set-user() to authenticate a user (ie "log them in") through the controller.

I suggest you to check out this thread, for some more specific information, but to sum it up:

  • You need to check if the loginState changed
  • You need to refresh the page if it did

Solution 1)

Step 1

You need to initialize a global variable like this:

let loginStateChanged = false;

And when the user logs in or out, you do:

loginStateChanged = true;

Step 2

You need to listen for "browser back-button events" and refresh the window if the login state has changed.

You can use the pageshow event like so:

window.addEventListener('pageshow', (event) => {
    var isBackNavigation = event.persisted || 
        (typeof window.performance != 'undefined' && window.performance.navigation.type === 2);

    // If the navigation type is a back navigation, and the login
    // State has changed, refresh the window
    if (isBackNavigation && loginStateChanged) {
        window.location.reload(); // reload the page
    }
});

Or with jQuery;

$(window).on('popstate', () => {
    // If the login State has changed, refresh the window
    if (loginStateChanged) {
        window.location.reload(); // reload the page
    }
});

Becuase the window refreshed, the loginStateChanged will be reset to its default value false .

Solution 2)

Or if you need to implement the solution for multiple tabs:

Step 1

Use localStorage and a global variable instead:

let isLoggedIn = JSON.parse(localStorage.getItem('isLoggedIn')); // Get the initial value
isLoggedIn = isLoggedIn != 'undefined' ? isLoggedIn : false; // If initial value is undefined, set it to false

And when the user logs in or out, you do:

isLoggedIn = /* login: true, logout: false */; // update global variable
localStorage.setItem('isLoggedIn', JSON.stringify(isLoggedIn)); // update localStorage variable

Step 2

window.addEventListener('pageshow', (event) => {
    var isBackNavigation = event.persisted || 
        (typeof window.performance != 'undefined' && window.performance.navigation.type === 2);

    // If the navigation type is a back navigation, and the login 
    // State has changed, refresh the window
    // Here you check, if the localStorage variable is different, than the global variable
    if (isBackNavigation && JSON.parse(localStorage.getItem('isLoggedIn')) != isLoggedIn) {
        window.location.reload(); // reload the page
    }
});

Solution 3)

If you want to refresh on any back or forward click, just use this code:

window.addEventListener('pageshow', (event) => {
    var isNavigation = event.persisted || 
        (typeof window.performance != 'undefined' && window.performance.navigation.type === 2);
    if (isNavigation) {
        window.location.reload();
    }
});

Solution 3 Test-files:

test1.html and test2.html (they are exactly the same):

<html>
    <head>
        <title>test</title>
        <script>
            window.addEventListener("pageshow", function ( event ) {
                var isNavigation = event.persisted || 
                    (typeof window.performance != 'undefined' && window.performance.navigation.type === 2);

                console.log("Is navigated through button? ", isBackNavigation);
                if (isNavigation) {
                    alert("reload!");
                    window.location.reload();
                }
            });
        </script>
    </head>
    <a href="test1.html">Test1</a>
    <a href="test2.html">Test2</a>
</html>

It will refresh the whole page on every navigation action. And on the opening of a new tab it will reload it anyways.

The best source I found for your problem was the following blog article that explains caching in a way that even I could understand: https://jakearchibald.com/2016/caching-best-practices/

TLDR: Don't try to fix this on the client side, let the server take care of this. Add the following response header on the server side:

Cache-Control: no-cache

@MauriceNino had already covered almost all the technical methods, though there is one more that exist in certain scenarios.

Not the best solution but if all your pages are created with certain dynamic url with parameters, you can just add a new parameter "v" or "version" = random login session key.

To make this happen, all and any URL's (that you don't want to cache) should be concatenated with above parameters. Create a centralized method to call ajax or pages and add this version parameter. Every time you login a new unique parameter will be created. Browser will always hit for a new request if the parameter is changed.

Though the down side to this is that your URL's won't be pretty. All your URL's would have to go through a filter (which i guess you would already have)

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