根据时间在脚本标签和样式表中附加动态版本(变量)

Posted

技术标签:

【中文标题】根据时间在脚本标签和样式表中附加动态版本(变量)【英文标题】:Append Dynamic version(variable ) in Script tag and stylesheet based on time 【发布时间】:2019-04-25 11:32:05 【问题描述】:
<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>

或者,

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>

我已经尝试过如下但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>

我正在尝试根据当前时间或某些动态变量在脚本标签和样式表中添加动态版本(变量)?

如果可能,请帮助我找到最短且有效的解决方案。

如何实现?

【问题讨论】:

是否需要日期和时间?我有一个类似的解决方案,但使用与日期和时间相对应的版本号 你能告诉我这个变量应该是动态的,并且一旦脚本或样式表被加载,就不能与之前的变量值匹配。 啊,我明白了。每次我推送代码时,我的版本都非常适合生产使用。不是基于reload 您的生产版本是否需要此功能以防止在您的网站的新版本中缓存或仅用于开发?如果您指定您想要的目的,我可以帮助您。 @molikh,我想知道,上面的标签位于 index.html 中,这个 index.html 是用于生产还是开发是否重要。如果你能帮助我,这可能会解决我的问题 【参考方案1】:

如果您正在寻找最短的解决方案,这个怎么样?

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

一个有价值的选择应该是:

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

好吧,你必须像下面这样转义结束脚本标记:

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

如何添加多个脚本的示例:

<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>

【讨论】:

谢谢,您能否请一些类似的脚本解决方案。我在 head 标签中有 7 个脚本加载,我需要的两个脚本类似于样式表。 请检查我的更新。顺便说一句,在问这些基本问题之前,您似乎需要使用搜索。 也许,这是一个基本问题。但是,我不知道。如果我正在尝试我的两个脚本,我在评论中的上述解决方案不起作用。你能建议我做错什么吗? 不工作也不显示在网络标签上【参考方案2】:

您可以通过 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>

取自 Stack overflow answer

【讨论】:

我已经尝试过了,但脚本没有加载到网络选项卡上。 这个怎么样? ***.com/questions/1866717/… 我认为这会对你有所帮助,但对我来说最好的方法是尽可能从后端完成所有这些工作。 Javascript 在浏览器中运行,因此用户必须等待所有这些计算和请求完成才能获得正确的 dom 视图。如果页面加载后出现脚本或 css 文件,我不确定用户体验是否相同。 ***.com/questions/20821720/…【参考方案3】:

您似乎对html & javascript 感到困惑。

不可能使用htmljavascript 混合来存档。


s-s-r(Server Side Render)

使用诸如Handlebars或其他模板引擎。

timestamp(以及您的版本标签)应该在生成 html 之前在服务器端呈现。

<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>

没有s-s-r(Server Side Render)

htmlHTTP 请求返回后,我们可以使用javascript 归档。

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

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

document.head.appendChild(script);

最好包装一个函数来完成这项工作。

【讨论】:

【参考方案4】:
<script [src]="'/assets/abc.js?v='+new Date.getTime();" type="text/javascript"></script>

如果它不工作尝试创建模型并这样做:

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

还有更多方法可以做到这一点。

【讨论】:

它不起作用,脚本未显示在网络选项卡上。 有点奇怪,你有没有试过把你的脚本放在标题上,看看它是否真的在加载?因为你说的很奇怪。【参考方案5】:

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>

为什么setInterval我们如何告诉浏览器“请每分钟检查一次条件是否为真”如果是,那么append new styleFile scriptFile注意:如果你愿意,也可以及时提供minutesseconds,但记得在if(...)中添加适当的条件

【讨论】:

【参考方案6】:

从我所做的所有测试来看,当使用 [0] 而不是 [6] 或任何其他值时,您尝试的最终尝试似乎完美无缺。另外为什么你有多个头标签?这是一个错字,你的意思是标题?它似乎适用于任意数量的标题。

但是如果可能的话,这种事情真的应该通过后端来处理。

【讨论】:

抱歉,打错了。更新的问题。它没有帮助【参考方案7】:

您的脚本未加载,因为它不是new Date.getTime(),而是new Date().getTime(),或者只是使用Date.now()。此外,为了防止浏览器缓存,您可以添加 no-cache 标头,例如使用 .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>

对于javascript函数

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');

【讨论】:

【参考方案8】:

虽然此处的其他答案正确描述了如何在脚本中执行此操作,但我想注意三点:

    您应该在构建时使用哈希而不是时间戳来执行此操作,否则,每次日期更改时,您的缓存都可能被清除。这不是一个很好的用户体验。有意识地了解何时以及为什么要获取此内容。 Webpack 有一个 nifty build plugin 用于在文件名中创建哈希。 使用headers 决定是否应获取新文件。 确保在任何运行时&lt;script&gt; 元素上设置async 属性,否则会降低性能,有时甚至会显着降低性能。搜索引擎会严重惩罚这一点。

```

```

但请注意,无论使用async 属性,附加脚本标记都会阻止渲染。 Read this for more details.

【讨论】:

您好,请举个例子以便更好地理解【参考方案9】:

我尝试使用上面的一些示例,但性能受到影响,因为每次用户登录时都会加载 js 文件。

以下方法将确保 js 仅在您提供新版本时加载。

第 1 步:在您的主布局页面中添加一个隐藏/(非隐藏)元素,如下所示,这将包含您的最新版本号。

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

第 2 步: 使用下面的脚本标签对您的 js 文件进行版本控制,请根据您的使用情况更新脚本类型。

<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>

【讨论】:

以上是关于根据时间在脚本标签和样式表中附加动态版本(变量)的主要内容,如果未能解决你的问题,请参考以下文章

仅在不存在时将脚本添加到头部

使用 JQuery 从 head 标签中动态删除样式

如何在 .html 标记内附加 jQuery 变量值

删除脚本和样式标签中的所有内容

vue 在同一个标签中根据不同条件绑定不同的class 的写法。。动态绑定class

jquery样式div并根据div标签添加标题