22

Problem: I have a site with dynamic content which needs to be reloaded every time the user sees it. This includes the use case when a user hits the back button on an another site and comes to the site needed to be reloaded. Most (all?) browsers don't refresh the site after this event.

My solution (which isn't quite working): http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript

window.onbeforeunload = function () {
    // This function does nothing.  It won't spawn a confirmation dialog
    // But it will ensure that the page is not cached by the browser.
}

But it still doesn't refresh the page.

Any ideas what can affect/block the desired behavior? Respectively any other solution suggestions for this problem?

edit:

Set following:

Cache-Control   private, must-revalidate, max-age=0
Expires Sat, 26 Jul 1997 05:00:00 GMT
Pragma  no-cache

and:

<meta name="cache-control" content="no-cache" />
<meta name="expires" content="0" />
<meta name="pragma" content="no-cache" />

still no success.

BenMorel
  • 30,280
  • 40
  • 163
  • 285
sorgenkind
  • 271
  • 2
  • 3
  • 8
  • you shouldn't attempt to prevent the browser from caching the page. when i use the back button, i expect the page that i was on to reappear as it was when i left it. but if that page has auto-updating elements then those should then continue to update when i return. – Dan D. Jan 28 '12 at 15:14
  • sadly, sometimes you need to, eg: https://www.quora.com/Why-dont-payment-gateway-pages-support-Back-Button-Refresh – ptica Jun 07 '17 at 09:56

11 Answers11

57

You should use a hidden input as a refresh indicator, with a value of "no":

<input type="hidden" id="refresh" value="no">

Now using jQuery, you can check its value:

$(document).ready(function(e) {
    var $input = $('#refresh');

    $input.val() == 'yes' ? location.reload(true) : $input.val('yes');
});

When you click on the back button, the values in hidden fields retain the same value as when you originally left the page.

So the first time you load the page, the input's value would be "no". When you return to the page, it'll be "yes" and your JavaScript code will trigger a refresh.

Joseph Silber
  • 193,614
  • 53
  • 339
  • 276
Ali Al-Naimi
  • 718
  • 7
  • 11
  • 3
    Worked for me. I had to use location.reload(true) to force a server reload otherwise it just reloaded from cache. – Kris Aug 07 '14 at 18:56
  • 1
    This means the whole page has to load, in order to decide it needs reloading, right? – Thanasis Ioannidis May 16 '16 at 13:11
  • 1
    Do not use `location.reload()` if your page may have been the result of a POST request. In this case, use `location.href = location.href` instead to avoid the browser warning about form resubmission. If needed, you can add a cache buster (e.g. `?_cache=123`) and/or use HTTP cache control headers. – Arc Jun 13 '16 at 12:19
  • I do not wanted to implement session/cookies and was looking for something simple. This worked for me - Thanks – Arpit Agarwal Oct 13 '16 at 02:59
  • 1
    @Archimedix : Uses of reload(**true**) will force to reload the current page from the server, so it won't be a problem. – David Létourneau Nov 08 '16 at 13:15
  • @DavidLétourneau this does not prevent the resubmission warning for POST, it will just force a reload in case the warning is confirmed. Chrome may not show the warning, but Firefox does. And of course you would expect a reload on POST to do a POST, not a GET. However by setting `href`, you trigger a GET instead. – Arc Nov 08 '16 at 13:29
  • Some ingenuity there! Thanks! – Jonathan Laliberte Jun 14 '17 at 02:22
  • 2
    For Chrome, `input type="hidden"` does not work. You have to use `input type="text" style="display:none"`. – Christian d'Heureuse Nov 12 '17 at 00:50
  • @Christiand'Heureuse, you're right, but I would prefer to use this styling instead of hiding it: `style="position: absolute; top: 0; left: 0; width: 1px; height: 1px; opacity: 0; filter: alpha(opacity =0);"` – parse Apr 18 '18 at 14:18
19

After trying out various different solutions I have found that the JavaScript Navigation Timing API works best for detecting interactions with the back button.

All you have to do is this:

if(!!window.performance && window.performance.navigation.type == 2)
{
    window.location.reload();
}

And it works well with all major browsers: http://caniuse.com/#search=Navigation%20Timing%20API

Is My Page Being Loaded from the Browser Cache?

Community
  • 1
  • 1
Hasan Akhtar
  • 222
  • 3
  • 7
4

You can use the window.onpageshow event to test if the page comes from the cache.

window.onpageshow = function (event) {
  if (event.persisted) {
    window.location.reload(); //reload page if it has been loaded from cache
  }
};

Note that this requires more modern browsers than some of the previous answers (such as IE11+). For more info on browser support see here

Rune Vejen Petersen
  • 3,142
  • 2
  • 26
  • 45
  • This is the only answer for this one - when you click back or forward, the page is loaded from the BFCache (not the HttpCache), which is a kind of "frozen" image of the page as you left it. The pageshow event will fire with that flag set. Unfortunately, it will not fire if the page is loaded from user navigation and cached by the "http cache". – gbjbaanb May 07 '18 at 21:53
1

this worked for me, in drupal 7 (php) whenever a user logs out, he can press the back button and able to visit the privileged pages. If a page is refreshed, then he is routed to a front page where he can't do anything.

    <?php 
        //refresh the page after log-out and back button
        if (!user_is_logged_in())
        {

          print '<input type="hidden" id="refreshed" value="no">
                 <script type="text/javascript">
                  onload=function(){

                    var e=document.getElementById("refreshed");
                    if(e.value=="no")e.value="yes";
                    else{e.value="no";location.reload();}
                  }
                </script>';
        }
  ?>

somebody posted here: thanks i hope it help you too.

bherto39
  • 782
  • 2
  • 9
  • 23
0

I found a solution: add no-store to the Cache-Control header. I did it in the http headers, but I guess it could work with meta tags too. Tested in Chromium and Firefox.

See also How to stop chrome from caching

Community
  • 1
  • 1
0

Try this :

header("Cache-Control: no-store, must-revalidate, max-age=0");
header("Pragma: no-cache");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");

// A date in the past

jogee31
  • 9
  • 1
0

You could use this code in a custom module :

<?php 
/**
 * Implements hook_init().
 */
function MY_MODULE_init() {
  drupal_add_http_header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate, post-check=0, pre-check=0');
}
?>
mouhammed
  • 894
  • 7
  • 15
0

This is what I'm using to reload page on browser Back Button:

if(performance.getEntriesByType("navigation")[0].type == "back_forward"){
    location.reload();
}
pdolinaj
  • 939
  • 11
  • 18
0

Does it help ?

Reload the page on hitting back button

Or with meta tags,

<meta http-equiv="cache-control" content="no-cache"> <!-- tells browser not to cache -->
<meta http-equiv="expires" content="0"> <!-- says that the cache expires 'now' -->
<meta http-equiv="pragma" content="no-cache"> <!-- says not to use cached stuff, if there is any -->

Not sure, the meta will help, but you can test it.

Community
  • 1
  • 1
Jashwant
  • 26,663
  • 15
  • 65
  • 99
-1

I think you need exactly reloading - window.location.reload(). But the main issue is cross browser simple solution. Code on PHP:

$inline_javascript = 'var uniqueString = ' . time() . ';' .
                     'if (uniqueString === window.name) {' .
                     '  window.location.relace();' .
                     '} else {' .
                     '  window.name = uniqueString;' .
                     '}';

And print it before css and js files in the .

-1

I think this question will help you.

[edit(Nickolay): here's why it works that way: webkit.org, developer.mozilla.org. Please read those articles (or my summary in a separate answer below) and consider whether you really need to do this and make your page load slower for your users.]

Nickolay's answer

Community
  • 1
  • 1
nuala
  • 2,663
  • 4
  • 26
  • 47