2

I have a .NET web applications which uses a lot of javascript. The .aspx and the .js files go hand-in-hand together. Problem: The .aspx files are always up-to-date on the client (not cached) but the .js files might well be cached. This is even a problem if the files are only cached for one session since users are spending many hours on my site and everytime I update a .aspx/.js pair users are running into a problem.

Now, I found a solution but I am not sure if there is perhaps a better solution or if my solution has a performance drawback.

This is my solution:

.js-References in .aspx:

<script type='text/javascript' src='../scripts/<%# GetScriptLastModified("MyScript.js") %>'></script>

So, the "GetScriptLastModified" will append a ?v= parameter like this:

protected string GetScriptLastModified(string FileName)
{
  string File4Info = System.Threading.Thread.GetDomain().BaseDirectory + @"scripts\" + FileName;
  System.IO.FileInfo fileInfo = new System.IO.FileInfo(File4Info);
  return FileName + "?v=" + fileInfo.LastWriteTime.GetHashCode().ToString();
}

So, the rendered .js-Link would look like this to the client:

<script type='text/javascript' src='/scripts/GamesCharts.js?v=1377815076'></script>

The link will change every time, when I upload a new version and I can be sure that the user immediately gets a new script or image when I change it.

4
  • If I remember correctly, Safari will not cache anything downloaded with a query parameter. So your solution will be correctly cached by all other web browsers except Safari. Commented Sep 22, 2010 at 6:54
  • It's a common solution, but you're better off having the version in the filename, for instance /scripts/GamesCharts_<version>.js as query parameters prevent proxy caching of resources. Commented Sep 22, 2010 at 7:00
  • Yes, that's the solution I have today: Renaming the files to myscript_v1.js. But then I also need to update all references to those files. Then the history in my source repository is broken. It works as expected but I am looking for an easier solution... Commented Sep 22, 2010 at 14:43
  • Well, have you tried adding the <scripts> tag in a contentplaceholder so that you can manually update the version in one place? Commented Jun 3, 2011 at 11:03

3 Answers 3

2

Safari refuses to cache URLs with query parameters. So instead of a query parameter you can use something like a versioned path and use mod_rewrite to remove it.

Something like:

<script type='text/javascript' src='/scripts/1377815076/GamesCharts.js'></script>

And in Apache config file (config for other servers left as homework):

RewriteEngine On
RewriteRule  ^/scripts/[0-9]+/(.+)$    /scripts/$1
Sign up to request clarification or add additional context in comments.

Comments

2

What we do in our environment is we manually increase the counter in the calling script :

<script type='text/javascript' src='/scripts/GamesCharts.js?v=1'></script>

Whenever there is any update to the js file , we just increment the counter :

<script type='text/javascript' src='/scripts/GamesCharts.js?v=2'></script>

Your method works automatically but it needs to retrieve the LastWriteTime every time the script being called. If its a high traffic site, it will increase the CPU processing.

1 Comment

Yes, but I am not fetching the last time write from disk every time. I keep a cache and when I deploy, I empty the cache. Additionally, the scripts are cached locally. I think our solution adds nearly no overhead.
0

Just a thought: You could probably just render the JS as an ASPX; I've done this for forceful reload of CSS before with a JSP. Not proud of that solution, but it's worked before.

<script type='text/javascript' src='/mycode/GamesCharts.js.aspx'></script>

Then just render the JS statically in the ASPX file.

3 Comments

If you're doing this, might as well configure your web server to serve js files as non-cached.
Absolutely; that's the right way to go if you want all of your JS dynamic. However, if you only have a few files that must be uncached, the above method works.
Well my .js files change once every few weeks. I do not want them to be totally dynamic. No way. I even configured my webserver with a no-expiry tag. But SOMETIMES they DO change and then I need a mechanism to force an update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.