强制浏览器使用新的CSS

时间:2020-03-06 14:25:31  来源:igfitidea点击:

有没有一种方法可以检查用户浏览器是否缓存了其他版本的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标记的辅助功能或者自定义控件的理想人选。