File versions using ?v=(file version) - javascript

I have seen some sites add a version parameter to their .css and .js files like style.CSS?v=60 meaning the file is of version 60. The sites I have seen to do this cache their files long in the future.
Do I need to add any new code to my files or can I just update my code and then when a change is made change the version parameter ?v=?

If you want to employ this technique, then the first step is to set your web-server to send far-future expires headers, for certain file types (CSS, JS, images, etc).
The next step is to invalidate them, by using either a query-string, or a version-name.
?v=1.2.12
or
js/my-lib/my-file-1.2.12.js
or
js/my-lib/1.2.12/my-file.is
Any of those will work.

Related

How do I display my project correctly in a server?

I sent my project to my server but no one cant see changes what i did in local mode(i have index.html and other js and php). I had the same problem with another project with index.php but soved adding this <?php time();?> at the end of scrip. Is there any similar solution for javascript?
This is what i did
<script src="assets/js/funciones.js?<?php time();?>"></script>
The problem is that you're changing static files, but not their filenames.
By default apache/nginx/etc serve static content with headers that say "cache this for a very long time" because it's static content, why would you not?
Tacking on random trash to the URL like you're doing with you JS is a kludge that permanently breaks all caching and ensures that users will repeatedly download the exact same static file every time they request a page. You can make the trash less random to break the cache less frequently, but it's still an inefficient kludge. [Albeit a popular one, to my immense annoyance.]
Ideally for resource bundles like JS and CSS, you make a new resource bundle file every time you change it, eg: somefile-v1234.js or somefile-20211007.js and update the reference in your HTML source. This has the side-benefit of ensuring that the versions of your resource bundles always match.
The same goes for any other static file: images, CSV, etc.
The trouble you're having now is that you've updated some HTML pages and the only way to break the cache is to have the user perform an action, like hitting CTRL+F5 to force a refresh.
There are a couple ways around this:
Change the Apache/Nginx/etc settings to set shorter expiries for static file cache headers. You may be able to target specific files like index.html, but YMMV.
Serve the content with PHP. Anything served via a PHP script will not have any cache headers set by default, as the assumption is that the output of a script is dynamic. You can also issue the caching headers yourself in PHP to control what gets cached for how long.
Lastly, you cannot solve this problem retroactively. If a user has a cached version of the HTML page that has not yet reached its expiration, the user MUST take action to break that cache. There's nothing that can be done server side because the valid cache tells the client that it doesn't have to ask the server.
Once you get to the point of your application being popular enough to warrant putting a CDN in front of it this problem gets much worse as now there's a cache in the middle that the user doesn't have control of, and it's potentially an expensive problem because some CDN providers charge a fee for forcing CDN cache invalidations.

How does "?v=" in HTML linking work?

I have been developing a website for testing new stuff, and I need to figure out the "?v=" thing. But I have no clue how it works, so can someone explain this to me please haha? Like how to, and how it works.
So what would this look like and how would the file names on the server vary for this:
<script src="assets/js/moticulous.js"></script>
<link rel="stylesheet" href="assets/js/platforms.css"/>
as opposed to this:
<script src="assets/js/moticulous.js?v=1"></script>
<link rel="stylesheet" href="assets/js/platforms.css?v=1"/>
This can be added to prevent Caching of js/css/image files. By adding ?anything=123 You force browser/client to download the updated version of js/css/image file from the server.
Read more on: https://css-tricks.com/can-we-prevent-css-caching/
That is a technique used to control caching of script, css and image files.
The browser will download the script file with the ?v=1 parameter (example"http://example.com/path/to/script.js?v=1") and cache it to the visitors disk. The next time the browser visits the page, if the URL is still "http://example.com/path/to/script.js?v=1" then the cached version will be loaded.
If you change the ?v=1 to ?v=2 then the cached version is no longer valid as the full URL is no longer the same as what the browser has cached. This results in a new file being downloaded, and cached. This forces recent changes to every visitor regardless of cache settings set at the server config or browser.
This technique is often used with a version number (likely why its a v=) to force a new download of the js when the software version gets updated.
In your backend code, you would replace the =1 part with whatever the current software version is to make this cache control dynamic. Alternately, you could increment the version number whenever the asset changes but that's less dynamic or more work to make it so.
The dummy HTTP GET string is passed to prevent caching as some browsers cache the .js and .css files. It is usually done to prevent the older version of the file from loading by the browsers via browser cache when a change is made to the .css or .js file. Adding the timestamp value to the name (as <filename>?<timestamp>) is more popular than adding the version as it forces the browser to download the files every time the page is viewed as no two request times have the same timestamp.

Loading a JS file from a CDN, how to prevent browser caching?

Every few hours (or less it depends) I will be updating a javascript file that will contain a JSON object that contains notifications that will appear on the website. This JSON object is what I will be updating periodically and so it cannot be cached by browsers.
The javascript will be hosted on a CDN, and this file will be on client websites like:
<script src="//example.com/1.7.1/my_file.js"></script>
How can I possible prevent browser caching in this type of situation?
I guess the best way would be for all clients to have the same javascript file, and then make an ajax request to pull down the messages? This way the "my_file.js" can be cached, but the ajax response will not be.
You can add a timestamp after the path my_file.js?time=currentTime
To keep the HTML clean you can add something like this in another local js file
$("head").append('<script type="text/javascript" src="yourPath?time=' + Date.now() + '"></script>');
Or you can use $.getScript, requirejs, etc.
It really depends on what CDN you use and the features available. Some approaches:
Instruct the CDN to cache the file for around an hour, so it'll automatically fetch a new one every hour (assuming someone is requesting). This means that users won't necessarily get the change immediately, but would be within half an hour of you changing
Along with that, Have the CDN send the end users a "no-cache" Cache-Control header. Depending on the CDN, this would simply be what your origin sends and you use some an override on the CDN (or one of the various means of instructing the CDN to cache it via headers, such as Surrogate-Cache-Control)
Alternatively, the above-mentioned versioning/timestamped URL. The downside of this is that it requires you to update any references to your file to include the version id. If your pages are auto-generated this is fine.
Allow the CDN to cache the file indefinitely, but make use of a "purge" or "invalidation" feature to force the CDN to request the new version the next time it is requested. This would mainly apply if you would have a reason to have the file not update for more than a few hours or a day.

Force browser to reload all cache after site update

Is there a way to force the clients of a webpage to reload the cache (i.e. images, javascript, etc) after a server has been pushed an update to the code base? We get a lot of help desk calls asking why certain functionality no longer works. A simple hard refresh fixes the problems as it downloads the newly updated javascript file.
For specifics we are using Glassfish 3.x. and JSF 2.1.x. This would apply to more than just JSF of course.
To describe what behavior I hope is possible:
Website A has two images and two javascript files. A user visits the site and the 4 files get cached. As far as I'm concerned, no need to "re-download" said files unless user specifically forces a "hard" refresh or clears their cache. Once a site is pushed an update to one of the files, the server could have some sort of metadata in the header informing the client of said update. If the client chooses, the new files would be downloaded.
What I don't want to do is put meta-tag in the header of a page to force nothing from ever being cached...I just want something that tells the client an update has occurred and it should get the latest once something has been updated. I suppose this would just be some sort of versioning on the client side.
Thanks for your time!
The correct way to handle this is with changing the URL convention for your resources. For example, we have it as:
/resources/js/fileName.js
To get the browser to still cache the file, but do it the proper way with versioning, is by adding something to the URL. Adding a value to the querystring doesn't allow caching, so the place to put it is after /resources/.
A reference for querystring caching: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
So for example, your URLs would look like:
/resources/1234/js/fileName.js
So what you could do is use the project's version number (or some value in a properties/config file that you manually change when you want cached files to be reloaded) since this number should change only when the project is modified. So your URL could look like:
/resources/cacheholder${project.version}/js/fileName.js
That should be easy enough.
The problem now is with mapping the URL, since that value in the middle is dynamic. The way we overcame that is with a URL rewriting module that allowed us to filter URLs before they got to our application. The rewrite watched for URLs that looked like:
/resources/cacheholder______/whatever
And removed the cacheholder_______/ part. After the rewrite, it looked like a normal request, and the server would respond with the correct file, without any other specific mapping/logic...the point is that the browser thought it was a new file (even though it really wasn't), so it requested it, and the server figures it out and serves the correct file (even though it's a "weird" URL).
Of course, another option is to add this dynamic string to the filename itself, and then use the rewrite tool to remove it. Either way, the same thing is done - targeting a string of text during rewrite, and removing it. This allows you to fool the browser, but not the server :)
UPDATE:
An alternative that I really like is to set the filename based on the contents, and cache that. For example, that could be done with a hash. Of course, this type of thing isn't something you'd manually do and save to your project (hopefully); it's something your application/framework should handle. For example, in Grails, there's a plugin that "hashes and caches" resources, so that the following occurs:
Every resource is checked
A new file (or mapping to this file) is created, with a name that is the hash of its contents
When adding <script>/<link> tags to your page, the hashed name is used
When the hash-named file is requested, it serves the original resource
The hash-named file is cached "forever"
What's cool about this setup is that you don't have to worry about caching correctly - just set the files to cache forever, and the hashing should take care of files/mappings being available based on content. It also provides the ability for rollbacks/undos to already be cached and loaded quickly.
i use a no-cache parameter for this situations...
a have a string constant value like (from config file)
$no_cache = "v11";
and in pages, i use assets like
<img src="a.jpg?nc=$no_cache">
and when i update my code, just change the $no_cache value, and it works like a charm.

getting related js files: What is the point of adding ?t=B48E5AB

I'm using CKEditor which is a multi-file library so the main js file calls other js and css files. I'm noticing that after the main file is called, additional files have a ?t=CODE added to them, so something like this, but the actual files don't have that extra ?t=B49E5BQ at the end.
http://site.com/ckeditor/config.js?t=B49E5BQ
http://site.com/ckeditor/extra.js?t=B49E5BQ
What's the point of this
P.S. Please feel free to add additional tags, because I'm not sure about this one.
This sort of trailing data is sometimes put into URLs for resources files like scripts/stylesheets so as to prevent caching of resources across re-deployments.
Whenever you change a resource, you change the code in HTML files/templates which require that resource, so that clients re-request the resource from the server the next time they load the page.
I would guess that the URL parameter is added to bypass any caching mechanisms. When a client sees the same URL with a different query parameter, that usually means the client can't use the cached version of the resource (in this case a JS file) and go to the server to fetch the latest version.
In HTTP, if a URL is the same in every way except for the URL parameters, a client can not assume that those files/resources are the same resulting object.
Which means:
http://site.com/ckeditor/config.js?t=B49E5BQ
is not the same as:
http://site.com/ckeditor/config.js?t=1234
It must be there to prevent caching.
I do this occasionally for images and script files. In my case, it's a meaningless argument (usually datetime) that just forces the browser to fetch a new copy every time.
If the parameter keeps changing, those files won't be cached on the client side.
Often this is easier than say, changing the name of the file to include a version number (jquery-1.6.2.js works nicely, but do you want to rename config.js to config-1.0.js, -2.0, etc. every time you make a change?
Like all the other answers, this simply forces the browser to grab the latest version when the querystring (?t=B49E5BQ) is changed. In our case, we simply add the date (?06022011).

Categories

Resources