Anyone know a server side trick to force a web browser to refresh?

Sc0tt - April 2, 2009 - 06:28

Thanks for any help with this.

I have a situation where my homepage is not being updated and am looking for a way to to force browsers to refresh and get the latest content. Anyone know any server side methods or other tricks to accomplish this?

Thanks again,
Scott

header( 'refresh: 5;

Jay Matwichuk - April 2, 2009 - 07:10

header( 'refresh: 5; url=http://www.example.net' );

Where '5' is the number of seconds until refresh.

Thanks for this but where

Sc0tt - April 3, 2009 - 03:40

Thanks for this but where does it go? htaccess? If it goes in page.tpl.php's then I don't think this will work. The browser will never see the new code because it thinks it already has the latest content.

I tried rewriting my urls with a timestamp to make the browser think its is a new url and force it to get the latest content. I used appache's mod rewrite in the .htacess file but this method didn't work because none of the links on the site work. In case anyone want to know how to do this, here is the code:

RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !time [NC]
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI}?time=%1 [R,L]

Any other ideas?

Thanks again,
Scott

The code I gave you is php

Jay Matwichuk - April 3, 2009 - 04:12

The code I gave you is php code. You can put it at the top of your page.tpl.php before your doctype, like this:

<?php header( 'refresh: 5; url=http://www.example.net' ); ?>

But be warned - this means every single page on your site will refresh every five seconds. If you only want it to work for individual pages, then I think you can just add that to the page in question, but you will need to enable the php filter module first, and select the php filter as the input type on the page you are editing.

1) I have a situation where

mm167 - April 3, 2009 - 03:57

1) I have a situation where my homepage is not being updated

and

2) am looking for a way to to force browsers to refresh and 3) get the latest content ...

if i were u, i would re-think

why 1) homepage not being updated? just homepage? or all the pages?
is 2) refresh a solution?

We go the drupal way. How about you?
http://www.drupalway.com

<?php header( 'refresh: 5;

Sc0tt - April 3, 2009 - 05:29

<?php header( 'refresh: 5; url=http://www.example.net' ); ?>

Doesn't work because the new code inserted into the page.tpl.php file is never accessed because the url has not changed and the cache lifetime is set to infinite.

I think I need a server side solution to to the htaccess file to somehow trick the browser into thinking the url or content has changed and it needs to read in the latest data.

Thanks very much for you help,
Scott

Did you try? Also, I think

Jay Matwichuk - April 3, 2009 - 05:56

Did you try?

Also, I think what you are talking about and what I am telling you are two different things. If I get you right, you are looking for a hard-refresh, forcing a re-download of all the elements on the page. Is that right?

Yes, but I don't think it can

Sc0tt - April 3, 2009 - 08:21

Yes, but It can't come from the browser side because everything is already cached. I think it has to come from the server (htaccess) and tell or trick the browser into re-downloading all page elements. I have many pages (including my home page) that won't update to the latest content. I had turned page caching on with a minimum lifetime of "none" which I believe caused the problem.

Thanks again,
Scott

I gotcha. Actually, your

Jay Matwichuk - April 3, 2009 - 14:04

I gotcha. Actually, your problem is fairly easy (though potentially time consuming) to fix, and puts you in a good spot.

What you do is append a version number to every element name - your stylesheets, scripts, images, flash, everything. So for example, If you have:

style.css
javascript.js
image.png
flash.swft

You rename the files to:
style.2.css
javascipt.2.js
image.2.png
flash.2.swf

Then you have to go in and rename all your file references within your (X)HTML. Since the browser doesn't have for example style.2.css cached, it will download the new file.

Why this puts you in a good position: Having everything cached will speed up your site. Each file requires an http request, and browsers will only make two http requests at a time to any given server. This means that the more http requests you have, the longer the line up takes, and the less http requests you have, the faster your site will load.

And since you have all your elements versioned, any time you update an element, you just change the version number, and it will automatically re-cache.

Thank you! But I believe I am

Sc0tt - April 3, 2009 - 19:56

Thank you! But I believe I am already doing something similar that should be forcing the style sheet to update every time it's changed. I'm appending its filename with a timestamp. The method has been working great for the past 9 months; but now it does not work on any pages that were accessed during the time I had "page cache" turned "on" and the "minimum cache lifetime" set to "none". Those pages are no longer getting the updated style sheet.

I've only made 1 change to Drupal core and it was to add the timestamp to the style sheet so users would always get the latest version. Here is the code:

**************************************
Drupal core change to have browser automatically update style sheet by appending time and date stamp. Got this from: http://www.webcoda.co.uk/blogs

edited /includes/common.inc and added the following text to the drupal_get_css() function.

function drupal_get_css($css = NULL) {
  $output = '';
  if (!isset($css)) {
    $css = drupal_add_css();
  }

  $preprocess_css = variable_get('preprocess_css', FALSE);
  $directory = file_directory_path();
  $is_writable = is_dir($directory) && is_writable($directory)
    && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)
    == FILE_DOWNLOADS_PUBLIC);

  foreach ($css as $media => $types) {
    foreach ($types as $type => $files) {
      foreach ($types[$type] as $file => $preprocess) {
// webcoda addition of timestamp to stylesheets
$csstimestamp = '?ts=' .filemtime('.' . base_path() . $file);
        if (!$preprocess || !($is_writable && $preprocess_css)) {
          if (!$preprocess && $type == 'module') {
            $no_module_preprocess .= '<style type="text/css" media="'.
              $media .'">&import "'. base_path() . $file . $csstimestamp .
              '";</style>' ."\n";
          }
          else if (!$preprocess && $type == 'theme') {
            $no_theme_preprocess .= '<style type="text/css" media="'.
            $media .'">&import "'. base_path() . $file . $csstimestamp .
            '";</style>' ."\n";
          }
          else {
            $output .= '<style type="text/css" media="'.
            $media .'">&import "'. base_path() . $file . $csstimestamp .
            '";</style>' ."\n";
          }
        }
      }
    }

    if ($is_writable && $preprocess_css) {
      $filename = md5(serialize($types)) .'.css';
      $preprocess_file = drupal_build_css_cache($types, $filename);
      $output .= '<style type="text/css" media="'.
        $media .'">&import "'. base_path() . $preprocess_file .
        '";</style>'. "\n";
    }
  }

  return $no_module_preprocess . $output . $no_theme_preprocess;
}

**************************************

I just can't figure out why web browser's that accessed pages during the time I had "page cache" "on" with "Minimum cache lifetime" set to "None" no longer update to a new css file with a new timestamp. Thats why I think I need some kind of a url change or other trick to force browsers to think its a new page and update everything.

Anyone have any ideas?

Thanks again,
Scott

 
 

Drupal is a registered trademark of Dries Buytaert.