3

I've noticed a solution that might help you to control caching of javascript files.

There is a method SPUtility.MakeBrowserCacheSafeLayoutsUrl. MSDN says this method: returns a new URL that will not be cached by the browser when the associated file changes.

It sounds awesome. I've tried using this method like so:

 <script type="text/jscript" src="<%=SPUtility.MakeBrowserCacheSafeLayoutsUrl("projectName/scripts/plugins/tapes_report_definition.js", false)%>" ></script>

So, it worked. It generated ?rev={MD5Hash_of_my_file.js} part at the end of the url. But after I changed this .js file, new MD5 hash did not get generated. ?rev part remained the same. I've tried iisreset, redeploy etc, but nothing helped. I've checked this method with Reflector and learned that MakeBrowserCacheSafeLayoutsUrl does not generate MD5 hash all the time, but gets it from internal SPVolitileCache object.

I thought I could clear this cache by deleting all files inside of these two folders:

  1. %APPDATA%\Microsoft\Web Server Extensions\Cache
  2. %USERPROFILE%\AppData\Local\Microsoft\WebsiteCache

Deletion did not help.SPUtility.MakeBrowserCacheSafeLayoutsUrl still returns the same value after javascript file is changed.

I've got three questions:

  1. How do I refresh SPVolitileCache after all?
  2. How do you force SPUtility.MakeBrowserCacheSafeLayoutsUrl generate new ?rev= without purging cache?
  3. Considering all above, does it even make sense to use SPUtility.MakeBrowserCacheSafeLayoutsUrl?

Any additional information will be greatly appreciated!

  • Hi Denis. I have also checked with reflector the SPUtility class. Indeed it uses an internal SPVolatileCache object, but that object is "zeroed out" by the constructor of the SPUtility class, and that being a static class, it should reinitialize and call the constructor on every IISReset. Would you mind chatting with me on this, so we might find the cause of the problem together? – Norbert Jan 29 '14 at 13:09
  • hi, yes, we could do that, but I need to reproduce the problem again. The main purpose of this question was "does it make sense to use MakeBrowserCacheSafeLayoutsUrl method?" I think IISreset did nothing to refresh the cache. I'm checking it now again. – Denis Molodtsov Jan 29 '14 at 17:56
  • I actually debugged the internal SharePoint Dlls and saw that after iisreset cache still remembers the old file somehow. – Denis Molodtsov Jan 29 '14 at 17:58
  • Well, I checked it again and it actually gets refreshed after iisreset, providing we are changing the contents of the file. I must have messed up something. – Denis Molodtsov Jan 29 '14 at 18:53
  • Glad to hear that, because I would have been really disappointed if this method prooved to be unreliable. :) – Norbert Jan 30 '14 at 9:03
2

I've checked it again and I confirm that this method is totally viable. The URL of a file gets refreshed after iisreset. This is exactly what I wanted to see.

  • 2
    Just to add: Refreshed if the file content changes. Very important to note, because the MD5 hash is calculated on the file contents, hence if the file contents don't change, the MD5 doesn't change even if it is being regenerated. – Dennis G Dec 8 '14 at 19:32
  • yes, good point – Denis Molodtsov Mar 15 '15 at 17:41
0

I would like to add this just as a comment but stackexchange won't allow that. So, here is my answer: For anyone looking to solve the issue of cached script elements inside a Content Editor web part (or a JSLink to a .js file), know that the SPUtility.MakeBrowserCacheSafeUrl method is a SERVER ONLY method and must be embedded on an ASPX page. Be sure you understand that you cannot just plop the code into a .js file or your Content Editor web part and have it function. It will not.

That being said, the method really is pretty worthless because you might as well just use the ScriptLink tag. ScriptLink will add the ?rev for you. The only time you might be tempted to use this method is if you are embedding script tags into a page which you should never do. That totally goes against the entire SOD framework and best practices and will likely not work with MDS.

The reason I found this page was because I have an InfoPath Form Web Part on a page and the previous developer used a separate .js file to make some buttons for it. The .js file for the buttons is referenced in a Content Editor web part. This is probably a common scenario but it is problematic because the file reference does not have a trailing ?rev unless added manually. Unless there is an actual client-side method that helps to generate some sort of ?rev, and I don't see how there could be, my vote is that this method is useless.

  • I like MakeBrowserCacheSafeLayoutsUrl because it works consistently across any file types including css, js, xml etc. That's why I don't have to memorize wheter to put files in 1033 folder, or specify Localizable=”False” or not. Should I use CSSRegister or ScriptLink? What should I use for XML? In the end, using embeded code <%= %> is no worse than using ScriptLink directly on ascx/aspx page. SOD is all very well, but this method does not suggest that you should use it for every single script. I only recommend using it when css or scripts should be run in any case. In other cases use SOD. – Denis Molodtsov Sep 15 '15 at 8:07
  • btw, there is CssRegistration Control that only expects files in \lang_ID\ folder, which makes it almost worthless in multilanguage environments. There is no way to override it with Localizible='False' attribute because it does not exist. MakeBrowserCacheSafeLayoutsUrl, on the other hand, will not expect you to store your css files in specific folders. – Denis Molodtsov Sep 15 '15 at 8:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.