views:

379

answers:

7

I've noticed an issue while developing my pages that's always bothered me: while Firefox (my general "dev" browser) always updates CSS and images when they change on the server, Internet Explorer does not always do this. Usually, I need to refresh the page in IE before it will ask the server for updated versions of things.

As I understand it, isn't the browser supposed to at least check the timestamps on all server side objects for each request, and then update them client side as necessary? Is there a way I can... not force, but.. "encourage" the browser to do this for certain items?

The main issue I'm having here is that I have some JavaScript on my pages that relies on the CSS being initialized a certain way, and vice versa. When one updates and the other does not (very common in IE when both are in their own external pages) it causes confusion, and occasional splatter results on the page. I can handle doing the "refresh the page" dance on my own for deving, but I don't want to have to encourage my users to "refresh the page or else" when I'm going on a scripting spree on the site.

Any advice would be greatly appreciated. The page itself updates without a hitch (it's PHP), so worst case scenario I could just spit the CSS and JavaScript out into the page itself, but that's really really ugly and of course I'm trying to avoid it at all costs.

+3  A: 

Add a little random query string at the end of all URLs. It's ugly but it works when developing. For example:

<link rel="stylesheet" type="text/css" href="/mycss.css?foo=<?php echo rand(); ?>"/>

You can do the same for scripts, background images, etc. (And don't forget to remove these things when your site goes live ;))

Etienne Perot
+3  A: 

This is only an issue during development, when the files are changing frequently. Once you've published the site, visitors will get the current version, and the caching mechanisms will do more or less what you want.

Rather than modify how my sites work, I have simply developed the habit of clearing my cache before refreshes during development. In Firefox, as you said, this is not usually an issue, but if I need to be really sure, I use Shift+Ctrl+Del, Enter (and my Clear Private Data settings leave only "Cache" checked.) And on IE, there's the old Shift+F5.

Of course, as others have mentioned, a random query string on your volatile files can save you a few keystrokes. But understand that this is in fact just for your own convenience and not really necessary for the production site.

harpo
+1 Ctrl-F5 the best solution if it's for dev only..
Nick
+2  A: 

If you're using apache, in your .htaccess for that css file:

<FilesMatch "mycssfile\.css$">
  Header set Cache-Control: "private, pre-check=0, post-check=0, max-age=0"
  Header set Expires: 0
  Header set Pragma: no-cache
</FilesMatch>
Keltex
+8  A: 

It's a good practice to design your site so that the client only needs to fetch external JavaScript and CSS once.

Set up external resources to expire 1 year in the future. Append a version number to each file name, so instead of "style.css", use "style-1.2.4.css" and then when you want to update the client's CSS, increment the version number.

Incrementing the version number forces the client to download the updated file because it is seen as a totally separate resource.

Dan Herbert
*facepalm* Why didn't I think of that?
Nicholas Flynt
That's indeed the proper way to do it, but when designing and changing the CSS code every refresh, the other solutions are more convenient, as long as the designer doesn't "forget" to come back to a more proper way later on.
Etienne Perot
One more thing is to have a script that appends a partial hash (or full hash) of the contents to the filename each time you deploy, like GWT does. You'd have to change the referenced filename too, which might not be too easy, but can be done if you have the know how.
Sudhir Jonathan
+2  A: 

It's better if you put the last-change timestamp as GET-data at the end of the source - in this way you'll be sure that there wont be any cache errors.

It's just dumb to remove the cache completely since it will result in slower pages.

Ivarska
A: 

Browsers store pages in the internal cache usually according to the instructions your server tells them. No, they are not required to reload the files if they appear to be unexpired based on the last check. Of course, when you hit reload, they do explicitly reload main page, but their behavior with respect to js and styles may differ.

I develop with Safari which has Develop -> Disable Caches menu for exactly that reason. I'm sure Firefox has something similar.

ilya n.
A: 

I use a slight twist on DanHerbert's method. I tend to use the same names for the stylesheets, but I affix a version number in the query string so that the browser sees the files as different whenever one chooses to incriment the version. Things still will get cached, but you can invalidate it at your choosing.

It's a bit cleaner than changing filenames and lends itself to being a centrally managed solution, especially in complex apps with lots of scripts and stylesheets coming from the four winds.

Wyatt Barnett