当前位置: 首页 > 知识库问答 >
问题:

如何追加时间戳到javascript文件中的标签url以避免缓存

周瀚
2023-03-14

我想在中的javascript文件源路径的末尾附加一个随机数或时间戳,以便每次页面重新加载时,它都应该下载一个新的副本。

应该是

<script type="text/javascript" src="/js/1.js?v=1234455"/>

我如何生成和附加此号码?这是一个简单的HTML页面,因此不能使用任何PHP或JSP相关代码

共有3个答案

华炜
2023-03-14

通过文档动态插入脚本。createElement('script'),然后在设置URL时,可以使用new Date()。getTime()以附加额外参数。

如果您担心在加载脚本之前javascript会执行,那么可以使用script元素onload回调(注意,对于IE来说,还有一些问题需要解决)

蔚学林
2023-03-14

如果您选择使用日期或随机数来附加到URI,那么您将为最终用户提供机会,使其获得相同的缓存文件,并且可能会暴露意外的安全风险。显式版本控制系统将不起作用。原因如下:

为什么“随机”和随机数都不好

对于随机数,您不能保证以前没有生成相同的随机数并提供给该用户。较小的“随机”数字集,或者比其他算法更频繁地提供相同结果的糟糕算法,生成相同字符串的可能性更大。一般来说,如果您依赖于JavaScript随机方法,请记住它是伪随机的,并且如果您试图依赖唯一性,例如您的脚本中的XSS漏洞补丁或类似的东西,也可能具有安全含义。我们不希望约翰尼在黑客先生碰巧来访的那天,用AJAX调用一个不再信任的第三方脚本来获得旧的缓存和未修补的JS文件。

为什么日期或时间戳也不好,但没有那么坏

将日期视为“唯一”标识符,JavaScript将从客户端生成日期对象。根据日期格式,意外缓存的可能性可能会有所不同。仅日期(20160101)就允许一整天的潜在缓存问题,因为早上的访问会导致foo.js?date=20160101,晚上的访问也是如此。相反,如果您指定向下到第二个(20160101000000)您的最终用户调用相同GET参数的几率会下降,但仍然存在。

少数罕见但可能的例外情况:

>

  • 在大多数时区,时钟每年都会重置一次

    由于某种原因重新启动时重置本地时间的计算机

    自动网络时间同步,使您的时钟在本地时间与服务器时间不同步时向后调整几秒/分钟

    在旅行时调整时区设置(IIS上的宇航员每隔几分钟就要经过一个区域……不要降低他们的浏览体验:P)

    用户喜欢重置系统时钟来干扰您

    为什么增量或唯一版本控制是好的:)

    对于一个仅支持的解决方案,我的建议是设置一个显式版本,每次更改文件时,您或您的团队成员可以简单地对其进行硬编码。手动做完全一样,在你的问题的相同代码将是一个很好的做法。

    你或你的团队应该是唯一编辑你的JS文件的人,所以关键不是每次你的文件都需要新鲜,我只需要在它改变时新鲜。浏览器缓存在您的情况下并不是一件坏事,但您确实需要告诉最终用户它应该在何时更新。基本上,在更新文件时,您希望确保客户端获得更新的副本。这样,您还可以恢复到以前版本的代码,而不必担心客户端缓存问题。唯一的缺点是您需要进行尽职调查,以确保在更新JS文件时确实更新了版本号。记住,仅仅因为某些东西不是自动化的,并不意味着它一定是不好的实践或糟糕的形式。使您的解决方案适合您的情况和可用资源。

    如果可能的话,我建议使用语义版本控制规则这样的表单,通过查看文件名(假设开发过程中没有人伪造版本编号)轻松识别向后或破坏兼容性。除非您有一个奇怪的用例,否则没有很好的理由每次都强迫客户机下载一个新的副本。

    通过本地存储在客户端自动增加版本

    如果您所追求的是一种前端方式,它可以自动为您生成唯一的版本号,这样您就不必显式地设置它,那么您必须实现某种本地存储方法来跟踪并自动增加文件版本。我在下面展示的解决方案将失去语义版本控制的能力,如果用户知道如何清除本地存储,还可能被重置。但是,考虑到您的选择仅限于客户端解决方案,这可能是您的最佳选择:

    <script type="text/javascript">
    (function(){
        /**
         * Increment and return the local storage version for a given JavaScript file by name
         * @param  {string} scriptName  Name of JavaScript file to be versioned (including .js file extension)
         * @return {integer}            New incremented version number of file to pass to .js GET parameter
         */
        var incrementScriptVer = function(scriptName){
    
            var version = parseInt(localStorage.getItem(scriptName));
    
            // Simple validation that our item is an integer
            if(version > 0){
                version += 1;
            } else {
                // Default to 1
                version = 1;
            }
    
            localStorage.setItem(scriptName, version);
    
            return version;
        };
    
        // Set your scripts that you want to be versioned here
        var scripts = ['foo.js', 'bar.js', 'baz.js'];
    
        // Loop through each script name and append our new version number
        scripts.map(function(script){
            var currentScriptVer = incrementScriptVer(script);
            document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>");
        });
    })();
    
    </script>
    

    为了完整起见,我要提到的是,如果您正在从生成“随机”编号或日期GET变量的旧系统转换为增量版本控制系统,请确保您不会使用新版本控制系统跳过任何可能随机生成的文件名。如果有疑问,请在更改方法时为GET变量添加前缀,或者简单地一起添加一个新的GET变量。示例:“foo.js?version=my_prefix_121216”或“foo.js?version=121216”

    通过AJAX调用和其他方法进行自动版本控制(如果有可能进行后端开发)

    就个人而言,我喜欢远离本地存储选项。如果该选项可用,它将是“最佳”解决方案。尝试让后端开发人员创建一个endpoint来跟踪JS文件版本,您可以始终使用对该endpoint的响应来确定您的版本号。如果您已经在使用像Git这样的版本控制,那么您可以选择让您的开发操作团队中的一员将您的版本控制绑定到您的提交版本,以实现一些非常好的集成。

    RESTful GETendpoint的jQuery解决方案可能如下所示:

    var script = "foo.js";
    
    // Pretend this endpoint returns a valid JSON object with something like { "version": "1.12.20" }
    $.ajax({
      url: "//yoursite.com/path/to/your/file/version/endpoint/" + script
    }).done(function(data) {
        var currentScriptVer = data.version;
        document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>");
    });
    

  • 子车睿
    2023-03-14

    方法1

    许多扩展可以通过这种方式添加,包括异步包含和脚本延迟。许多广告网络和高流量网站使用这种方法。

    <script type="text/javascript">
    (function(){ 
         var randomh=Math.random();
         var e = document.getElementsByTagName("script")[0];
         var d = document.createElement("script");
         d.src = "//site.com/js.js?x="+randomh+"";
         d.type = "text/javascript"; 
         d.async = true;
         d.defer = true;
         e.parentNode.insertBefore(d,e);
     })();
    </script>
    

    方法2(AJZane的评论)

    小而鲁棒的包含。您可以准确地看到JavaScript在哪里被触发,并且它比方法1更不可定制。

        <script>document.write("<script type='text/javascript' src='//site.com
        /js.js?v=" + Date.now() + "'><\/script>");</script>
    
     类似资料:
    • < code>fd.append("upload ",file)产生, 产生, 但我需要这个, 这是我的代码:

    • 问题内容: 我可以在不生成编译的.pyc文件的情况下运行python解释器吗? 问题答案: 来自“ Python 2.6的新增功能- 解释器更改” : 现在,可以通过向Python解释器提供-B开关,或者通过在运行解释器之前设置 PYTHONDONTWRITEBYTECODE环境变量来阻止Python编写.pyc或.pyo文件。此设置可作为Python程序的 变量使用,并且Python代码可以更改

    • 我正在使用Guava缓存热数据。当缓存中不存在数据时,我必须从数据库中获取数据: 我的问题是当数据不存在于数据库中时,我希望它返回并且不做任何缓存。但Guava保存与缓存中的关键字,并抛出一个异常,当我得到它: com.google.common.cache.CacheLoader$InvalidCacheLoadExcION: CacheLoader为shisoft键返回null。 我们如何避免

    • 问题内容: 如何在注入Jenkins时将文本追加到文件中 我希望看到 25在哪里 这是我的尝试 错误: 版本:= 1.0。$ {env.BUILD_ID}:替换错误 注意文件在当前目录中 问题答案: 是一个groovy变量,而不是一个shell变量。由于您使用了单引号(),因此groovy 不会 替换字符串中的变量,并且Shell也不知道。您需要使用双引号并让groovy进行替换 或使用外壳程序知

    • 问题内容: 我想建立一个不牺牲SEO的ajax网站。我的问题是:如果我的页面上有这样的链接: …当单击每个链接时,我想用相应的标签更新地址栏。因此,如果单击“猫”链接,则当前位置为http://example.com/#cats,我可以用它来显示我的Ajax内容。如果javascript关闭或用户是搜索引擎,他们将直接转到/ cats 问题答案: 您可以更改属性,它会更改当前的锚标识符,而无需导航

    • 问题内容: 在java中如何追加文本到存在的文件中? 问题答案: Java 7+ 如果你只需要执行一次,则使用Files类很容易: 注意:NoSuchFileException如果文件不存在,上述方法将抛出。它还不会自动追加换行符(追加到文本文件时通常会需要此换行符)。 但是,如果你要多次写入同一文件,则上述操作必须多次打开和关闭磁盘上的文件,这是一个缓慢的操作。在这种情况下,使用缓冲写入器更好: