7
<script src="/assets/abc.js?v='+new Date.getTime();" type="text/javascript"></script>

<link href="/assets/cder.css?v='+new Date.getTime();"  rel="stylesheet"></link>

or,

var myVariable = Math.floor(Math.random() * 999999999999);
<script src="/assets/abc.js?v='+myVariable ;" type="text/javascript"></script>

<link href="/assets/cder.css?v='+new Date.getTime();"  rel="stylesheet"></link>

I have tried this as below but the script is not loading on network tab.

<script type="text/javascript>
    var script = document.createElement('script');
    script.setAttribute('src', '/assets/abc.js?v=' + new Date.getTime());
    var head1 = document.getElementsByTagName("head")[0];
    head1.appendChild(script);
</script>

I am trying to add dynamic version(variable ) in script tag and stylesheet based on current time or some dynamic variable?

If possible, Please help me with the shortest and efficient solution.

How to achieve that?

Mahi
  • 2,846
  • 2
  • 23
  • 54
  • 1
    Is date and time necessary? I have a similar solution but using version number as apposed to date and time – Luke Walker Nov 27 '18 at 11:42
  • Can you please show me it the variable should be dynamic and should not match with the previous variable value once script or stylesheet is loaded. – Mahi Nov 27 '18 at 11:47
  • Ah i see. My version works well for production use for every time i push code. Not on a `reload` basis. – Luke Walker Nov 27 '18 at 11:48
  • do you need this for your production version to prevent caching in new versions of your website or just for development? if you specify for what purpose you want this I can help you. – molikh Nov 30 '18 at 08:52
  • @molikh, I am wondering, the above tag resides in index.html and does it matter if this index.html is for production or development. If you can help me in either, this may solve my problem – Mahi Nov 30 '18 at 09:19

9 Answers9

5

If you are looking for the shortest solution, how about this?

<script>document.write('<link href="/assets/cder.css?v=' + Date.now() + '" rel="stylesheet" />');</script>

A worthy alternative should be:

<script>
    var link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = '/assets/cder.css?v=' + Date.now();
    document.body.appendChild(link);
</script>

Well, you must escape the closing script tag as follows:

<script>document.write('<script src="/assets/abc.js?v=' + Date.now() + '"><\/script>');</script>

An example of how to add several scripts:

<script>
  var scripts = [
    '/assets/abc.js',
    '/assets/def.js',
  ];

  for (var i = 0; i < scripts.length; i++) {
    var script = document.createElement('script');
    script.onerror = function() {
      alert('Could not load ' + this.src);
    };
 
    script.src = scripts[i] + '?v=' + Date.now();
    document.body.appendChild(script);
  }
</script>
Victor
  • 4,652
  • 1
  • 22
  • 27
  • Thanks, Can you please some similar solution for script as well. I have 7 script loading in head tag and the two scripts I need similar as stylesheet. – Mahi Nov 30 '18 at 19:24
  • 1
    Please check my update. By the way, it seems you need to use the search before asking such basic questions. – Victor Nov 30 '18 at 19:37
  • – Mahi Nov 30 '18 at 19:56
  • Maybe, this is a basic question.But, I am not aware of it. This above solution in comment of mine is not working, if I am trying for my two scripts. Can you please suggest what I am doing wrong. – Mahi Nov 30 '18 at 20:03
  • is not working nor showing on Network tab – Mahi Nov 30 '18 at 20:32
  • I'm pretty sure that you are doing something wrong. Therefore, firstly, make sure that these files are available on your server. Then make sure that your browser console does not hide any HTTP requests. And, of course, double check the source of your HTML page. – Victor Nov 30 '18 at 21:18
  • However, your both shortest solutions is working but alternative solution is not visible on Network tab. This is the issue I am facing from starting – Mahi Dec 01 '18 at 02:10
  • Run the code snippet that I added to my answer and check your browser console. If you don't see two "Not found" requests on your console, but you got two pop-ups, it means your browser is not configured properly. Otherwise, there is some thing wrong on your page. – Victor Dec 01 '18 at 06:43
2

You could do this dynamically from javascript.

<script>
var my_awesome_script = document.createElement('script');
my_awesome_script.setAttribute('src', '/assets/abc.js?v='+new Date.getTime()); //was missing single quote
document.head.appendChild(my_awesome_script);
</script>

taken from Stack overflow answer

Mark Eriksson
  • 1,421
  • 10
  • 18
Vaggelis Ksps
  • 310
  • 4
  • 12
  • I have tried this but script is not being loaded on network tab. – Mahi Nov 24 '18 at 19:21
  • what about this? https://stackoverflow.com/questions/1866717/document-createelementscript-adding-two-scripts-with-one-callback/1867135#1867135 – Vaggelis Ksps Nov 24 '18 at 19:22
  • I think that this will help you but the best approach for me is to do all these from backend if it is possible. Javascript runs in the browser so the user has to wait for all these calculations and requests to finish to get the proper view of the dom. I am not sure if the user experience would be the same if a script or a css file come after the page load. https://stackoverflow.com/questions/20821720/calling-javascript-function-to-include-stylesheet-fails – Vaggelis Ksps Nov 24 '18 at 19:32
1

It seems that you are confused with html & javascript.

It's impossible to use html which is mixed up with javascript to archive something.


With SSR(Server Side Render)

Using such as Handlebars or another template engine.

The timestamp(as well as your version tag) should be rendered in server side before html was generated.

<script src="/assets/abc.js?v='+new Date.getTime();" type="text/javascript"></script>

<link href="/assets/cder.css?v='+new Date.getTime();"  rel="stylesheet"></link>

Without SSR(Server Side Render)

We can archive with javascript after html is returned by HTTP request.

let script = document.createElement('script');

script.setAttribute('src', `somefile?v=${Date.now()}`);

document.head.appendChild(script);

It's better to wrap a function to do this job.

Victor
  • 276
  • 1
  • 6
0
<script [src]="'/assets/abc.js?v='+new Date.getTime();" type="text/javascript"></script>

if its not working try to create model and do it like this:

this.someModel = "/assets/abc.js?v='"+new Date.getTime();
<script [src]="script" type="text/javascript"></script>

there are also more ways to do it.

Talg123
  • 1,190
  • 1
  • 6
  • 14
  • Its not working, The scripts are not showing on network tab. – Mahi Nov 22 '18 at 20:29
  • Kinda wierd, have you tried to put ur script on header and see if its actully loading? becouse that wierd what your saying. – Talg123 Nov 26 '18 at 18:25
0

const time = new Date(2018, 10, 24, 22); // you can provide minutes and seconds if you want
const today = new Date();
const head = document.querySelector('html head');
const body = document.querySelector('html body'); 

const styleFile = '<link href="/assets/cder.css?v=' + today.getTime() + '"  rel="stylesheet"></link>';
const scriptFile = '<script src="/assets/abc.js?v=' + today.getTime() + '" type="text/javascript"></script>';

setInterval(() => {
  if ((time.getDate() === today.getDate()) && (time.getMonth() === today.getMonth()) && (time.getFullYear() === today.getFullYear()) && (time.getHours() === today.getHours())) {
    head.append(styleFile);
    body.append(scriptFile);
  }
}, 60000);
<html>
  <head>
    <!-- here we will append style file -->
  </head>
  <body>
    <div>some dummy text</div>
    <!-- here we will append script file -->
  </body>
</html>

why setInterval? that how we tell the browser "please check every minute if the condition true" if it's, so append new styleFile and scriptFile .
Note: you can provide minutes and seconds in time as well if you want but remember to also add the appropriate condition in if(...){}

Amir Fawzy
  • 419
  • 5
  • 10
0

From all the testing I have done it seems that the final attempt that you tried works flawlessly when using [0] instead of [6] or any other value for that matter. Also why do you have multiple head tags? was this a typo and you meant header? it seems to work with any number of headers.

But really this type of thing should be handled via backend if possible.

COLBY BROOKS
  • 301
  • 1
  • 4
0

While other answers here correctly describe how to do this in a script, I want to note three things:

  1. You should do this at build-time using hashes, not timestamps, otherwise, every time the date changes your cache could be cleared. That's not a great user experience. Be intentional about when and why you're fetching this. Webpack has a nifty build plugin for creating hashes in file names.
  2. Use headers to drive whether a new file should be fetched.
  3. Make sure you're setting the async attribute on any run-time <script> element, otherwise it degrades performance, sometimes significantly. Search engines penalize this heavily.

```

```

But note that appending a script tag regardless of using the async attribute will block rendering. Read this for more details.

Jefftopia
  • 1,788
  • 1
  • 22
  • 42
0

Your script is not loading because its not new Date.getTime() but new Date().getTime() or just use Date.now(). Additionally To prevent browser cache you can add no-cache header for example using .htaccess

<filesMatch "\.(js|css)">
  FileETag None
  <ifModule mod_headers.c>
     Header unset ETag
     Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
     Header set Pragma "no-cache"
     Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
  </ifModule>
</filesMatch>

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/javascript "access plus 1 seconds"
ExpiresByType text/css "access plus 1 seconds"
</IfModule>

and for javascript function

function appendJS(url) {
  var s = document.createElement('script');
  s.src = url + '?v=' + Date.now();
  document.body.appendChild(s);
}

function appendCSS(url) {
  var s = document.createElement('link');
  s.rel = 'stylesheet';
  s.href = url + '?v=' + Date.now();
  document.body.appendChild(s);
}
appendJS('/assets/abc.js');
appendCSS('/assets/cder.css');
ewwink
  • 15,852
  • 2
  • 35
  • 50
0

I tried using above some examples, but the performance was impacting, as the js file will load every-time the user logs in.

The below approach will make sure the js loads only when you give a new build.

Step 1: Add an hidden/(non hidden) element as below in your master layout page, this will contain your latest build number.

<p id="BuildNumber">Build Number : @System.Diagnostics.FileVersionInfo.GetVersionInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "<yourDllName>.dll")).FileVersion
</p>

Step 2 : Use below script tag to version your js files, please update the script type as per your usage.

<script>
    var script = document.createElement('script');
    script.setAttribute('src', '/Scripts/Common/<fileName>.min.js?v=' + document.querySelector('#BuildNumber').innerHTML.split(': ')[1]);
    script.type = 'text/babel';
    document.head.appendChild(script);
</script>