强制浏览器使用新的CSS
有没有一种方法可以检查用户浏览器是否缓存了其他版本的CSS,是否强制浏览器提取新版本?
解决方案
我们可能应该只共享一个公共的祖先类,然后如果需要,可以使用单个js命令轻拂它。
<body class="style2"> <body class="style1">
等等。
无需使用js,我们只需将css文件名保留在会话变量中即可。当对主页发出请求时,我们只需将css链接标记与会话变量名称组合在一起即可。
由于ccs文件名不同,因此我们可以强制浏览器下载该文件,而无需检查浏览器中先前加载的内容。
我知道这个问题是专门针对Cand的,我认为Windows Server具有某种风味。由于我对这两种技术都不甚了解,因此我将给出一个适用于PHP和Apache的答案,我们可能会从中得到一些帮助。
如前所述,只需根据特定查询在页面正文中设置ID或者类即可(例如,在PHP中)
<?php
if($_GET['admin_page']) {
$body_id = 'admin';
} else {
$body_id = 'normal';
}
?>
...
<body id="<?php echo $body_id; ?>">
...
</body>
而且CSS可以针对以下目标:
body#admin h1 {
color: red;
}
body#normal h1 {
color: blue;
}
等等
至于强制CSS下载,我们可以在Apache中使用mod_headers的mod_expires或者mod_headers模块来执行此操作,.htaccess中的此操作将停止缓存CSS文件:
<FilesMatch "\.(css)$"> Header set Cache-Control "max-age=0, private, no-store, no-cache, must-revalidate" </FilesMatch>
但是由于我们可能不使用apache,所以对帮助不大:(
回答问题1
我们可以编写从System.Web.UI.Control继承来重写Render方法的服务器控件:
public class CSSLink : System.Web.UI.Control
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
if ( ... querystring params == ... )
writer.WriteLine("<link href=\"/styles/css1.css\" type=\"text/css\" rel=\"stylesheet\" />")
else
writer.WriteLine("<link href=\"/styles/css2.css\" type=\"text/css\" rel=\"stylesheet\" />")
}
}
并在MasterPage中插入此类的实例:
<%@ Register TagPrefix="mycontrols" Namespace="MyNamespace" Assembly="MyAssembly" %>
...
<head runat="server">
...
<mycontrols:CSSLink id="masterCSSLink" runat="server" />
</head>
...
我不知道这是否正确用法,但我认为我们可以使用查询字符串强制重新加载css文件:
<link href="mystyle.css?SOME_UNIQUE_TEXT" type="text/css" rel="stylesheet" />
我记得几年前曾使用此方法强制重新加载网络摄像头图像,但是时间可能已经过去了……
正如jeroen所建议的那样,我们可以进行以下操作:
<link href="StyleSelector.aspx?foo=bar&baz=foz" type="text/css" rel="stylesheet" />
然后,StyleSelector.aspx文件应如下所示:
<%@ Page Language="cs" AutoEventWireup="false" Inherits="Demo.StyleSelector" Codebehind="StyleSelector.aspx.cs" %>
和StyleSelector.aspx.cs像这样:
using System.IO;
namespace Demo
{
public partial class StyleSelector : System.Web.UI.Page
{
public StyleSelector()
{
Me.Load += New EventHandler(doLoad);
}
protected void doLoad(object sender, System.EventArgs e)
{
// Make sure you add this line
Response.ContentType = "text/css";
string cssFileName = Request.QueryString("foo");
// I'm assuming you have your CSS in a css/ folder
Response.WriteFile("css/" + cssFileName + ".css");
}
}
}
这将根据查询字符串参数向用户发送CSS文件(实际上是任何文件,请参阅安全说明)的内容。现在,最棘手的部分是执行条件GET,这是用于检查用户是否在缓存中具有页面的奇特名称。
首先,我强烈建议我们阅读RSS黑客的HTTP条件GET,这是一篇很棒的文章,介绍了HTTP条件GET机制的基础。相信我,这是一本必读的书。
我已经对SO问题发布了类似的答案(但使用PHP代码,对不起),我可以使用http标头检查动态页面是否已更改。将代码从PHP移植到C应该很容易(如果以后有时间,我会做的。)
安全说明:使用(" css /" + cssFileName +" .css")之类的方法是非常不安全的,因为我们可能会发送相对路径字符串,从而可能向用户发送其他文件的内容。我们将想出一种更好的方法来找出要发送的CSS文件。
设计说明:我们可能想使用IHttpModule或者IHttpHandler而不是.aspx页,但是这种方式很好用。
我喜欢jeroen的建议,将查询字符串添加到样式表URL。我们可以在上次修改样式表文件时添加时间戳。在我看来,它是为我们生成LINK标记的辅助功能或者自定义控件的理想人选。

