I have seen many websites that include at their JavaScript and CSS external resources things like this:
filename.js?v=3cc1b79c2abb
And:
filename.css?v=7bbb71ecd5eb
The "?v=..." things at the end...
What is this? And for what is this useful?
Thank you!
Cheers :)
These are a form of "Cache Busting" - they force the browser to download the latest version of the file, rather than taking a chance at loading an old file from cache.
There is something more deeper - why do we need cache busting?
For efficiency sake we have to make the browser cache the resource files. For that to work we set last modified date as a very old date (say, 01-Jan-1970 00:00:00.000) and expiry date long into the future. These 2 things will make the browser cache the files so that they are not requested from the server again. That is very efficient. However, that causes a problem when you update the application. None of the resources will be downloaded again! To work around that we configure the build tool to append a version number query string unique to the build at the end of resource URLs. It is typical to use build timestamp or a uuid or the source repository version number (in case of version control tools like SVN which give a unique version number to every commit) as the version number string appended to the end of the resource URLs. That forces the browser to download new version whenever the application is updated.
This is your own version/keyword v=7bbb71ecd5eb of js and css, After use this, there would not be cache in browser with your older javascript and css.
Which means your new update of css and javascript would be applied without any cache.
It's to force the browser to download the file instead of getting it from cache.
For example, you have this url with css : styles.css?v=blablabla, but later you change css and want to have these changes to be seen instantly (instead of waiting when browser cache will expire or forcing user to press Ctrl + F5) you change it to something like styles.css?v=otherblablabla. Browser sees it as different url so it have to download it.
It's just a parameter in query string, and because the url points to static resource, these parameters are ignored by web server.
You could also see something like this image.png?1392469113262. It's just a parameter named 1392469113262 that has no value. image.png is static resource so this parameter will be ignored by server. These numbers are usually some timestamp and it's the often the best way to force browser to not cache image (or any other resource).
Related
When I saw many sites' source code, parameters were passed to the linking file (CSS/JavaScript).
In the Stack Overflow source, I got
<script type="text/javascript" src="http://sstatic.net/js/master.js?v=55c7eccb8e19"></script>
Why is master.js?v=55c7eccb8e19 used?
I am sure that JavaScript/CSS files can't get the parameters.
What is the reason?
It is usually done to prevent caching.
Let's say you deploy version 2 of your new application and you want to cause the clients to refresh their CSS, you could add this extra parameter to indicate that it should re-request it from the server. Of course there are other approaches as well, but this is pretty simple.
As the others have said, it's probably an attempt to control caching, although I think it's best to do so by changing the actual resource name (foo.v2.js, not foo.js?v=2) rather than a version in the query string. (That doesn't mean you have to rename files, there are better ways of mapping that URL to the underlying file.) This article, though four years old and therefore ancient in the web world, is still a quite useful discussion. In it, the author claims that you don't want to use query strings for versions because:
...According the letter of the HTTP caching specification, user agents should never cache URLs with query strings. While Internet Explorer and Firefox ignore this, Opera and Safari don’t...
That statement may not be quite correct, because what the spec actually says is
...since some applications have traditionally used GETs and HEADs with query URLs (those containing a "?" in the rel_path part) to perform operations with significant side effects, caches MUST NOT treat responses to such URIs as fresh unless the server provides an explicit expiration time...
(That emphasis at the end is mine.) So using a version in the query string may be fine as long as you're also including explicit caching headers. Provided browsers implement the above correctly. And proxies do. You see why I think you're better off with versions in the actual resource locator, rather than query parameters (which [again] doesn't mean you have to constantly rename files; see the article linked above for more). You know browsers, proxies, etc. along the way are going to fetch the updated resource if you change its name, which means you can give the previous "name" a never-ending cache time to maximize the benefit of intermediate caches.
Regarding:
I am sure that Js/CSS files can't get the parameters.
Just because the result coming back is a JavaScript or CSS resource, it doesn't mean that it's a literal file on the server's file system. The server could well be doing processing based on the query string parameters and generating a customized JavaScript or CSS response. There's no reason I can't configure my server to route all .js files to (say) a PHP handler that looks at the query string and returns something customized to match the fields given. Thus, foo.js?v=2 may well be different from foo.js?v=1 if I've set up my server to do so.
That's to avoid the browser from caching the file. The appending version name has no effect on the JavaScript file, but to the browser's caching engine it looks like a unique file now.
For example, if you had scripts.js and the browser visits the page, they download and cache (store) that file to make the next page visit faster. However, if you make a change the browser may not recognize it until the cache has expired. However, scripts.js?v2 now makes the browser force a re-fetch because the "name's changed" (even though it hasn't, just the contents have).
A server-side script generating the CSS or JavaScript code could make use of them, but it is probably just being used to change the URI when the the content of the file changes so that old, cached versions won't cause problems.
<script type="text/javascript">
// front end cache bust
var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];
for (i=0;i<cacheBust.length;i++){
var el = document.createElement('script');
el.src = cacheBust[i]+"?v=" + Math.random();
document.getElementsByTagName('head')[0].appendChild(el);
}
</script>
This is to force the browser to re-cache the .js file if there has been any update.
You see, when you update your JS on a site, some browsers may have cached the old version (to improve performace). Sicne you want them to use your new one, you can append something in the query-field of the name, and voíla! The browser re-fetches the file!
This applies to all files sent from the server btw.
Since javascript and css files are cached by the client browser, so we append some numeric values against their names in order to provide the non-cached version of the file
"I am sure that JavaScript /CSS files can't get the parameters"
function getQueryParams(qs) {
qs = qs.split("+").join(" ");
var params = {},
tokens, re = /[?&]?([^=]+)=([^&]*)/g;
while (tokens = re.exec(qs)) {
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
}
return params;
}
This is referred to as Cache Busting.
The browser will cache the file, including the querystring. Next time the querystring is updated the browser will be forced to download the new version of the file.
There are various types of cache-busting, for example:
Static
Date/Time
Software Version
Hashed-Content
I've wrote an article on cache busting previously which you may find useful:
http://curtistimson.co.uk/front-end-dev/what-is-cache-busting/
I've seen that a lot and I just don't know what it means. This, for example:
<script src="http://server.com/file.js?y=2345678" type="text/javascript"></script>
If it is in deed possible to 'catch' the value of 'y' in the javascript file, how would that be?
Thank you.
PS. I know what mod_rewrite is and that is not the answer, just in case :)
This is to force the browser not to cache the file, by making it believe that it is a dynamic file with get parameter rather than a static one.
This is often used to facilitate caching of the JS file. You set a far-future Expires header which means the browser may cache it for a very long time. If you change something in the file you also update the number in the querystring, which will make the browser refetch the file. This works because caching is for unique filenames and the querystring is part of the filename (as far as the browser is concerned).
A similar approach to this is to use rewrite rules in the web server to have some part of the file name which it doesnät care about. Here's a Nginx rule to show what I mean:
rewrite ^/style\..*\.css$ /style.css;
I use this rule to have filenames like style.42750cad6.css, which always points to the file style.css. The text in the middle is changed whenever I change style.css. The difference between the first approach is that this does not use the querystring so the caching will work in more browsers.
ok the way i see it in two ways.
it can be used to load js without caching
for every request to the server, the server might log information(if logging is enabled), if i am using it for analytics i can therefore use a different parameter for locations and from the log i can analyse and get required details.
There are a lot of questions and answers on SO related to my problem [I want the browser to cache js/css forever. During a new release if some of the js/css files have been updated, the browser should reload and cache them.]
This solution seemed most appropriate to me :
What is an elegant way to force browsers to reload cached CSS/JS files?
However, there is just one thing that I am unable to figure out.
The solution makes use of last_modified_time. However, I am not allowed to use it. I need to use some other mechanism.
What are the options? Is there a possibility of pre-calculating the versions during build and updating(replacing) them in jsps via build script (before deployment, so that the version numbers are not calculated on run time)? Any existing tool for this purpose? I use Java/Jsp.
We always use
file.css?[deploytimestamp]
This way the CSS file is cached for each deployment at the client. The same goes for our minified javascript. Is this an option for you?
It may not be the best way, but this is what I am doing now:
All of my js/css have a [source control = svn] revision number
References in my jsp are like /foo/path1/path2/xyz000000/foo.
Build Step 1 - Generate a map of css|js files and their revision numbers
Build Step 2 - Replace xyz000000 references in jsps with a hash of svn revisions
A rule in url rewriter to direct all /foo/path1/path2/xyz<767678>/foo. to /foo/path1/path2/foo.[js|css]
Infinitely cache the css|js files
Whenever there is a commit, the revision number changes and so do the references in .jsp
Generate an md5-hash of each css file after deployment. Use this hash instead of the timestamp in the url of the css.
file.css?[hash of file.css contents]
It may be wise to calculate the hashes once after deployment and store them to gain some performance. You could store them in a database, or even in a PHP array in a separate file that is included in your website code.
I have a list of js files, css and images which doesn't need to load from server every time, but if there is any update in files or bug fixes, only during that time I want to replace the files from browser cache, I know there is no access to browser cache, but is there any other ways to do so? My application will be used by specific users (known people), where I can install any program in their system, can anybody suggest me efficient way to do so? I don't want to load the files every time from server by setting 'no-cache'.
The most effective way to force the browser to refresh certain files at certain times is to add an arbitrary extra query string to the link:
<script type="text/javascript" src="http://mywebsite.com/js/scripttoload.js"></script>
then change to:
<script type="text/javascript" src="http://mywebsite.com/js/scripttoload.js?V=2"></script>
Next time the page is requested the browser will think this is a new file. There are loads of other ways with headers etc but this works well
No, there isn't.
Javascript doesn't have access to the cache - the browser doesn't expose this information to the javascript engine.
A commonly-used trick is to set the cache for the files to last for ages, so that they aren't requested again. However, when you want them to be updated, you can append a timestamp to the filename after a question mark. EG:
<link rel="stylesheet" href="style.css?123211212"/>
Every time the number changes, the browser thinks it's a different file and will re-download it. If the number doesn't change, then it uses the cached version.
What I do is, as part of the build process, rename all the statically referenced files to something involving their md5 hash. Then I set the headers so that they're cached for the max possible time. As soon as they change, they get a new name, so there's never an issue.
I have a webapp written in PHP and i generate the headers with header() function.
The problem is that when I'm making changes to the javascript code of my app, on clients side, the old javascript will not be executed because is cached to the clients browsers.
How can I automate the process of header expiration? I assume that is has to be a better way than modifying that function each time I modify the javascript code.
The only bullet-proof solution is to change filenames of server-side resources:
From: Yahoo's Best Practices for Speeding Up Your Web Site:
Keep in mind, if you use a far future Expires header you have to change the component's filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component's filename[...]
Of course this process must be automated. We are appending JavaScript file contents hash into file name.
Change the URI to the script with each release.
This can be done by adding a query string. You can automate this by, for example, taking the revision number from your version control system and inserting it into your template.
This will allow you to have long expiry times (for optimal caching) and still get fresh JavaScript each time a new release is published (so long as the HTML document isn't loaded from the cache (but they tend to have short cache times compared to JS)).
The best way to version javascript files is to include a version number in their filename. When you rev the code, you bump the version number and then you rev any web pages that include the JS file to refer to the new filename. You then only need to expire the web pages themselves and they will automatically refer to the new JS files. The JS files can have very long expiration (months or years) so you get maximum caching benefit for them.
This also ensures that you get a consistent set of JS files.
This is how jQuery does it with versioning.
Since you don't provide much detail only the general pointer:
Usually you can configure the Expires and other header params in the webserver - either globally and/or per "folder" etc.
You can make the JS file expire for example after 1 hour... this way you would know that 1 hour after a change all clients will be using the new JS file...
IF you need the change to take effect immediately even for clients currently active the header won't help much - you would have to do some AJAX magic...