避免Javascript/Css缓存

8

我已经搜索了很多关于这个问题的内容,但是找不到任何真正能起作用的解决方案:我们正在构建一个使用大量javascript/css文件的web应用程序,这些文件可以随时修改。重点是我们需要客户端浏览器始终获取脚本的最新版本。

我们尝试添加GET查询(?v=CurrentDate),但浏览器会一直加载旧的脚本,直到您按下刷新几次或按CTRL+F5为止。

我们想避免的一件事是将那些文件存储在不同的文件夹中,例如/scripts/v1.0/,然后/scripts/v2.0/...

我们正在使用ASP.NET MVC 5,Bootstrap和JQuery。一个重要的事情是:我们只想避免一些脚本/css缓存,而不是全部避免。

非常感谢您的帮助! 谢谢!


1
你尝试使用缓存控制头了吗?- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control - Sergei Kutanov
据我所知,缓存控制头是针对所有资源的,对吗?或者你可以指定要避免缓存哪些资源? - tincho87
当加载页面时,浏览器会发出多个请求,包括在您的HTML中包含的CSS和JS文件。因此,您可以为这些资源返回不同的标头。我不知道您使用的是哪个Web服务器,但Apache肯定可以让您这样做。 - Sergei Kutanov
但你可以指定不想每次重新加载哪些资源吗?我的意思是,我只想重新加载被修改的“app”资源,而不是全部资源。 - tincho87
1
可以的。这里有一个有用的htaccess代码片段,你可以看到fileMatch允许你过滤需要应用头部信息的资源。 - Sergei Kutanov
好的!我会检查一下我们是否可以在IIS上实现,因为我们是asp.net mvc。 - tincho87
1个回答

12

浏览器缓存是指浏览器存储远程资源结果的能力。该过程相当简单:它会记住资源请求的url和响应。如果在资源被缓存期间再次请求该资源,浏览器将从缓存中提供保存的副本,从而节省带宽和时间。

如果您向资源调用添加一个始终唯一的参数,浏览器将始终重新加载它,因为参数已更改,浏览器将认为这是不同的资源。

通常,以秒(PHP 时间戳)或毫秒(JavaScript 时间戳)为单位的timestamp将确保您的资源始终重新加载:

JavaScript:

<script src id="myScript"></script>
<script type="text/javascript">
   // change path to match your file:
   let resourcePath = '/js/someScript.js';

   document.getElementById('myScript').src = resourcePath + '?v=' + Date.now();
</script>

PHP:

<script src="/js/someScript.js?v=<?=time();?>"></script>
注意:你可以对任何其他资源(例如.css或媒体资源)执行相同操作以禁用缓存。还要注意,你并没有真正禁用缓存——这不是那么容易做到的,并且因浏览器而异。你允许缓存,但总是请求不同的资源,因为它具有虚假参数,该参数不断更改(并且可以从v重命名为其他任何内容,例如?no-cache=)。

是的,你说得对。但是例如我有这个脚本/assets/global/scripts/sidebar.js?v=636615547606956030,其中v=是请求时刻的当前日期和时间,但如果我进行更改,需要刷新浏览器几次才能加载更改。这可能是浏览器的问题吗?它在本地和我们的客户端上都发生了。 - tincho87
@tincho87 如果参数不同,那么你所描述的技术上是不可能的。很可能是在更改内部资源之前尝试加载该资源。 - tao
没错!这就是让我感到困扰的原因……我不知道为什么更改没有在第一次刷新时加载。如果我更改请求的值,服务器应该返回新文件。 - tincho87
2
你实际上可以在Chrome控制台的网络选项卡中检查它是从哪里加载的。我确信你会发现它是从服务器加载的。只要有唯一参数,它就会一直加载。所以要么你的应用程序没有每次都应用它,要么服务器需要一些时间将其保存在资源中,并且你在服务器上实际更改之前就请求了它。 - tao
1
有时候浏览器加载得很好,但有时候你必须刷新几次...我会继续调查这个问题。我认为这可能是浏览器的问题。 - tincho87

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接