This article will guide users on how to immediately show the changes made in their assets after deployment without waiting for the cache to clear.
Introduction
We always encounter a problem when it comes to the latest code deployed on our servers. The page cached the JavaScript, thus making our updates on the scripts to not immediately take effect.
Background
The approaches below will give you an idea on how to make our pages know that there was already an updated version of the script and should be evaluated immediately by the page. We should also take into consideration the page' performance, that's why we will go to use the global localstorage
for some of the approaches.
First Approach
This approach will be suitable for the page with code behind.
On the ASPX markup, reference your CSS or JS files like this:
<link rel="stylesheet" type="text/css"
href="<%=AppendVersion("/Styles/myCSS.css")%>" />
On the ASPX code behind, add the following code:
Public Shared Function AppendVersion(ByVal filePath As String) As String
Dim fileInfo As FileInfo = New FileInfo(Current.Request.MapPath(filePath))
Dim cacheVersion As String = fileInfo.LastWriteTime.ToFileTime.ToString
Return filePath & "?v=" & cacheVersion
End Function
Second Approach
This approach will be suitable for the page without code behind. In addition, we are going to use the window localstorage
. The snippet for detecting the local storage below was from Mathias Bynens from this article.
On the ASPX markup, add the script
:
<script type="text/javascript">
var storage = (function() {
var uid = new Date,
storage,
result;
try {
(storage = window.localStorage).setItem(uid, uid);
result = storage.getItem(uid) == uid;
storage.removeItem(uid);
return result && storage;
} catch(e) {}
}());
var cached = function(name,value) {
if(storage.getItem(name) != null){
return (storage.getItem(name).indexOf(value) >= 0)? true : false ;
}else{return false;}
};
var GetFile = function(path) {
return path.substring(path.lastIndexOf('/')+1);
};
var execScript = function (script) {
var newfunction = new Function(script);
newfunction();
};
function RefJSVersioning(objUrl){
var req = new XMLHttpRequest();
req.open('HEAD', objUrl, false);
req.send(null);
var headers = (Date.parse(req.getResponseHeader
('Last-Modified'))/10000).toString().split('.')[0];
var source = objUrl + '?' + headers;
var fn = GetFile(objUrl);
if (storage) {
if(storage.length > 0){
if (!cached(fn + 'source',source)){
req = new XMLHttpRequest();
req.open('GET', objUrl, false);
req.send(null);
storage.removeItem(fn + 'source');
storage.removeItem(fn + 'content');
storage.setItem(fn + 'source', source);
storage.setItem(fn + 'content', req.responseText);
execScript(req.responseText);
}else{
execScript(storage.getItem(fn + 'content'));
}
}else{
req = new XMLHttpRequest();
req.open('GET', objUrl, false);
req.send(null);
storage.setItem(fn + 'source', source);
storage.setItem(fn + 'content', req.responseText);
execScript(req.responseText);
}
}
};
</script>
How to use:
<script type="text/javascript">
RefJSVersioning("/Scripts/myScript.js");
</script>
Screenshot of the script stored on Local Storage:
This approach also works with pages displayed inside an i-frame.
Reference
History
-
31st July, 2014
-
3rd June, 2023
- Updated code to stop using
eval()
because it is consuming a lot of memory - Added new function
execScript
- Updated header value for precise modified time. Instead of dividing with 100,000, it was changed to 10,000.
- Updated screenshots on how to debug scripts from local storage