强制浏览器使用新的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标记的辅助功能或者自定义控件的理想人选。