如何防止网页中CSS文件的缓存?

34

我正在学习开发xhtml、css网页。经常我在CSS中进行更改,但由于浏览器缓存,它不会反映在页面上,如果我手动清除缓存,它就会显示最新的代码效果。有没有什么方法可以在代码中加入来防止浏览器缓存?请给予任何建议。


1
这个问题涉及到许多元标记来防止缓存:https://dev59.com/6nM_5IYBdhLWcg3whznx,但你最好修改服务器返回的头信息。 - Matthew
如果您正在进行开发工作,请关闭缓存。您使用的是哪种浏览器? - Antonio Bakula
@Matthew:好的提示,你应该将其添加为答案。当然,缺点是你关闭了页面上的所有缓存,而不仅仅是CSS。 - magnattic
@Matthew:不,我认为开发目的最好的选择是在浏览器上禁用缓存,而不是搞乱服务器设置。 - frenchie
@frenchie:就像往常一样,这取决于您的情况。有些情况下更改HTML可能会更好。例如,如果您正在测试浏览器兼容性,则必须在所有浏览器中更改设置。或者如果您要在不同的PC上向不同的人显示页面。 - magnattic
我的意思是,禁用缓存的元标记方法可能会因浏览器而异,不太可靠。 - Matthew
10个回答

61

您可以通过JavaScript或服务器端代码向样式表URL附加一个随机查询参数。这不会改变要加载的CSS文件,但它将防止缓存,因为浏览器检测到不同的URL并且不会加载缓存的样式表。

<link rel="stylesheet" type="text/css" href="http://mysite/style.css?id=1234">

谢谢。你刚刚为我节省了很多时间和麻烦。+1 - Rudi Kershaw
函数 rs( $length = 8 ) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $rs = substr( str_shuffle( $chars ), 0, $length ); return $rs; } - Louis Ferreira
2
这在2022年仍然相关吗? - Abregre
1
@Abregre 我有这种感觉。请遵循此答案的评论:https://dev59.com/GXI-5IYBdhLWcg3w6dG2#1614568 - NDewolf
仍然有效。重要的是您实际使用随机参数而不是每次都相同。 - magnattic

9

您可以创建一个具有GetVersion方法的类,该方法将返回应用程序版本(例如构建号或构建日期)。

对于asp.net应用程序,在标记中,您可以像这样指定:

<script src="Scripts/some.js?version=<%= Common.GetVersion%>" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="~/styles/Style.css?version=<%= Common.GetVersion%>" />

这将强制浏览器重新加载文件,因为每次构建(或至少每个版本)都会更改静态文件的URL的一部分。

2
非常好的想法,这样你就可以在推送新的构建时重置缓存。 - George Birbilis

6
没有捕获: 将可变字符串放在css路径的末尾,如下所示:
<link rel="stylesheet" type="text/css" href="style.css?2016-12-3:10 13 30"/>

版本更改时刷新:

<link rel="stylesheet" type="text/css" href="style.css?v=1.1.0"/>

4
如果您使用Chrome作为开发浏览器,有两个选择:
1)当您按住“重新加载页面”按钮一秒钟时,会出现一个菜单,提供进行硬页面重新加载的可能性。
2)在检查器设置中,您可以强制浏览器永远不缓存文件。
我认为通过在浏览器上禁用缓存处理此问题更容易、更快捷,也更少麻烦,而不是在服务器配置中进行处理。

3
由于问题中还包含ASP.net标签,我想在Maxim Kornilov的答案(https://dev59.com/cGcs5IYBdhLWcg3wRB3h#12992813)上进行扩展,并介绍我如何在ASP.net MVC上使用他的想法,使URL变得特定于Web应用程序构建(他的示例是使用ASP / ASP.net WebForms语法而不是MVC和Razor Pages的新Razor语法):
1)添加到Global.asax.cs中Web应用程序的主类(称为MvcApplication)
#region Versioning

public static string Version => typeof(MvcApplication).Assembly.GetName().Version.ToString(); //note: syntax requires C# version >=6

public static DateTime LastUpdated => File.GetLastWriteTime(typeof(MvcApplication).Assembly.Location);

#endregion

someProperty => someReadOnlyExpression 语法只是 C# 6 可能的一种简写方式,其等同于 someProperty { get { return ... ;} }

2)在 Content/_Layout.cshtml 文件中,我曾使用以下代码来在页面页脚显示构建编号和构建日期(基于 web 应用程序的主要程序集):

Version @ViewContext.Controller.GetType().Assembly.GetName().Version (@string.Format("{0:yyyy/MM/dd-HH:mm:ss}", @File.GetLastWriteTime(ViewContext.Controller.GetType().Assembly.Location)))

我把它改成了更简单的形式:

Version @somewebappname.MvcApplication.Version (@string.Format("{0:yyyy/MM/dd-HH:mm:ss}", somewebappname.MvcApplication.LastUpdated))

3) 它通过在_Layout.cshtml中硬编码链接来加载CSS(仍在重构中),我将其更改为:

<link href='@Url.Content("~/Content/Site.css?version=" + somewebappname.MvcApplication.Version)' rel="stylesheet" type="text/css" /> 

如果有人在网页中右键单击并查看源代码,则会看到:

<link href='/Content/Site.css?version=2.1.5435.22633' rel="stylesheet" type="text/css" /> 

这是因为CSS URL具有虚拟参数版本,感谢虚拟参数版本的存在。

如果使用随机数,则会在每次页面加载时获取CSS,这通常是不需要的,特别是如果您已经将新的Web应用程序构建推送到Web服务器而不是单个页面更改(这样您就可以访问可注入到URL中的构建号)。

请注意,要实现自动递增生成版本号,在Properties/AssemblyInfo.cs中,我使用了以下代码(请参见如何在Visual Studio中实现自动递增版本号?):

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.*")] //don't use boh AssemblyVersion and AssemblyFileVersion with auto-increment

1

不要使用HTML编写<link>标签,而是使用PHP代码。在<link>标签的结尾处使用PHP mt_rand()函数,它会生成一个随机数,因此您的样式表将永远不会被缓存。

<?php echo "<link rel='stylesheet' type='text/css' href='style.css?'".mt_rand().">"; ?>

1

这可以通过 .htaccess 文件完成。将以下代码放置在名为 .htaccess 的文件中,位于您网站的根目录下:

<filesMatch "\.(html|htm|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>

这是为了避免每次手动刷新缓存而设置的。 - Wes Cossick
2
这在asp.net中不起作用;这不是框架中头部的工作方式。 - frenchie
1
ASP.NET 有类似的机制,但是使用 web.config 来实现。 - George Birbilis

0
如果您使用的是Google Chrome浏览器,只需按下CTRL + F5键即可强制刷新。CSS将会更新为本地机器或服务器上的样式。您也可以使用.htaccess文件,但这更多是针对可能是暂时性问题的永久性解决方案。CSS缓存有助于加快页面加载速度,因此我不建议完全禁用它。

0

您可以在链接中使用随机版本ID。例如,使用以下内容:

<link   href=<%="'mystyle.css?version="+ DateTime.Now.ToString("yyyyMMddhhmmss") +"'"%>   rel="stylesheet" type="text/css"/>

其中myStyle.css是样式表文件,DateTime.Now.ToString("yyyyMMddhhmmss")函数用于生成随机不同的版本ID。通过使用此随机版本ID,浏览器强制重新加载您的CSS。


-4
  • 在Chrome浏览器中按下F12键打开开发者工具
  • 然后右键单击重新加载按钮 - 点击(清除缓存并强制重新加载)

10
实际上,我知道的所有浏览器(不包括移动设备)按下ctrl + F5都会强制清除缓存。 - Matthew
在常见的浏览器中,在页面加载完成后按一次应该足以刷新页面的缓存。 - magnattic
Ankush Jain,我现在正在做同样的事情,但我不想每次都这样做,希望有一种方法可以让我不必每次都这样做,并且默认浏览器可能不会这样做。 - haansi
仅按下 F5Ctrl+RGUI Refresh button 可能不会改变任何内容。考虑按(Google Chrome) Shift+F5Ctrl+Shift+RShift+ GUI Refresh button。另外,您真的会直接要求用户强制清除缓存吗?更多信息:https://www.ghacks.net/2018/01/24/google-chrome-hard-reload-vs-normal-reload/#:~:text=You%20activate%20the%20function%20with,from%20the%20web%20page%20again 取决于浏览器。 - Artfaith
这是我刚开始学习编程时给出的答案。每次收到关于这个答案的评论时,我都会笑。 - Ankush Jain
显示剩余2条评论

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