通过脚本标记与GET

时间:2019-06-27 03:46:05

标签: javascript http caching etag

在过去的几天里,我一直在缓存地狱,而我开始变得有点挣扎。

所需结果
我想在网站上包含一个JS文件,并对其进行缓存和/或仅在服务器上更改了文件时才获取该文件的新副本。我不能在文件名中使用版本标记或哈希。文件名需要保持一致。

我在哪里
根据我的理解,使用Etags进行阅读后,这是一个完美的解决方案。它们将在文件更改时更新,并且如果标签不匹配,则会发送文件的新版本。当我通过浏览器请求文件时,这似乎可行

因此您可以看到,在第一个请求上我得到200,下载大小为292 B,在第二个请求上,因为标签匹配,我得到304,下载大小为137 B(我假设只是标头大小)。大! 这正是我想要的。

enter image description here

我的请求标头中查找etag: enter image description here

我的问题
现在,当我从浏览器请求文件时,此方法有效,但是在脚本标签中添加js文件不会以相同的方式发送请求标头。因此,打开以下html文件

<!DOCTYPE html>
<html>
    <body>
        <script src="https://myTestSite.com/testCache.js"> 
        </script>
    </body>
</html>

因为if-none-match请求标头不存在,所以每次都提取我的js文件。当使用html脚本标记时,如何复制在上述情况下观察到的行为? enter image description here enter image description here

TL; DR
在使用html脚本标签而不是简单的浏览器GET请求时,如何使用Etags仅请求修改的JS文件?

3 个答案:

答案 0 :(得分:1)

另一个选择(也许更简单)是在资源URI的末尾添加一个随机查询字符串:

<script src="https://myTestSite.com/testCache.js?version=<random_value>"></script>

这仍然意味着您正在从服务器获取相同的文件(服务器在返回资源时将忽略查询字符串),因此您不必在后端进行任何更改。

随机值可以是uuid,这将确保随机性。密钥也可能不需要version

答案 1 :(得分:0)

也许您应该尝试使用MLHttpRequest下载文件:

<!DOCTYPE html>
  <html>
    <body>
    <script> 
    (() => {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', "https://myTestSite.com/testCache.js");
      xhr.setRequestHeader('if-modified-since', '/*...*/')
      xhr.setRequestHeader('if-none-match', '/*...*/')
      //add more headers if you need
      xhr.onreadystatechange = function(){
          if(this.readyState == 4){
              if(this.status == 200){
                  //succeed
              }else{
                  //failed
              }
          }
      },
      xhr.send();
    })()
    </script>
  </body>
</html>

答案 2 :(得分:0)

我得到了它,但是并没有完全按照我的预期工作。这就是我最终要做的。

在我要提供js文件的目录中,添加了.htaccess文件

<FilesMatch "\.(js|css)$">
    Header set Cache-Control "no-cache, must-revalidate"
</FilesMatch>

我意识到,如果我将js文件本地添加到缓存中,它将始终从本地缓存中拉出,甚至从不向服务器发出请求。因此,即使Etag已更改,我的客户端也永远不会知道,因为该文件已在本地缓存。

因此,我决定完全不缓存文件并重新验证。因此,尽管我确实有一些HTTP标头的开销,但我将始终获得最新文件,而不必每次都提取整个文件。