8

I've been searching a lot about this, but I can't find any solution that really works: we're building a web app using lot of javascript/css files, which are modified at anytime. The thing is that we need that the client's browser always gets the last version of the script.

We tried adding the GET query (?v=CurrentDate), but the browser keeps loading the old script until you hit refresh a few times or do CTRL+F5.

One thing we want to avoid is to store those files in different folders like /scripts/v1.0/, then /scripts/v2.0/...

We're using ASP.NET MVC 5, Bootstrap and JQuery. One important thing: we only want to avoid some scripts/css caching, not everything.

I really appreciate your help! Thanks!

tincho87
  • 349
  • 1
  • 4
  • 12
  • 1
    did you try using cache-control header - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control – Sergei Kutanov May 10 '18 at 15:40
  • as far as I understand, cache-control header is for all the resources, right? or you can specify which resources you want to avoid caching? – tincho87 May 10 '18 at 15:47
  • while loading a page the browser makes several requests including for css and js files included in your html. Therefore you can return different headers for those resources. I don't know which web server you're using, apache will let you do this for sure – Sergei Kutanov May 10 '18 at 16:11
  • but you can specify which resources you don't want to reload everytime? I mean, I only want to reload the "app" resources that were modified, not all the resources. – tincho87 May 10 '18 at 16:19
  • 1
    Yes you can. Here's a useful gist for htaccess, as you can see fileMatch allows you to filter resources the header to be applied to – Sergei Kutanov May 10 '18 at 16:29
  • Good point! I'll check if I can do that on IIS, we're asp.net mvc. – tincho87 May 10 '18 at 16:36

1 Answers1

12

Browser caching is the ability of a browser of storing results from remote resources. The process if fairly simple: it remembers the url the resource was requested from and the response. If, while the resource is cached, the resource is requested again, rather than making the call, the browser serves the saved copy from cache, as it saves bandwidth and time.

If you add a parameter that is always unique to a resource call, the browser will always reload it, because the parameter will be changed and the browser will assume it's a different resource.

Typically, a timestamp in either seconds (php timestamp) or milliseconds (javascript timestamp) will make sure your resource will always be reloaded:

JavaScript:

<script src id="myScript"></script>
<script type="text/javascript">
   // change path to match your file:
   let resourcePath = '/js/someScript.js';

   document.getElementById('myScript').src = resourcePath + '?v=' + Date.now();
</script>

PhP:

<script src="/js/someScript.js?v=<?=time();?>"></script>

Note: you can do the same for any other resource (.css or media resources), to disable caching. Also note you're not, technically, disabling caching - that's not so easy to do and differs from browser to browser. You are allowing caching but you're always requesting a different resource, because it has the bogus parameter which keeps changing (and which could be renamed from v to anything else, for example, to ?no-cache=).

tao
  • 82,996
  • 16
  • 114
  • 150
  • Yes, you are right, but for example I have this script /assets/global/scripts/sidebar.js?v=636615547606956030 where v= is the current date and time at the moment of the request, but if I make a change, I need to refresh the browser a few times before it loads the changes. Could it be a browser thing? It happens locally and on our clients. – tincho87 May 10 '18 at 16:15
  • @tincho87 if the parameter differs, what you describe is technically impossible. It's likely that you're trying to load the resource before the change is made inside it. – tao May 10 '18 at 16:20
  • exactly! that's what is freaking me out...I don't know why the changes aren't loaded at the first refresh. It's supposed that if I change the value of the request, the server should return the new file. – tincho87 May 10 '18 at 16:26
  • 2
    You can actually check in the **Network** tab of Chrome console where it was loaded from. I'm certain you'll discover it was loaded from the server. Always (if it has unique param). So either your application is not applying it each time or the server takes some time to save it in the resource and you're requesting it before it's actually changed on the server. – tao May 10 '18 at 16:27
  • 1
    It's weird...sometimes the browser loads well, but sometimes you have to refresh it a few times...I'll keep investigating the issue. I think it could be a browser issue. – tincho87 May 10 '18 at 17:00