【问题标题】:Prevent scripts from being cached programmatically防止脚本以编程方式被缓存
【发布时间】:2011-07-01 02:30:32
【问题描述】:

我想问一下有没有办法阻止 Firefox 缓存脚本(.js 文件)。

我有一个项目(ASP.Net Web 应用程序)在 Firefox 上存在缓存问题。当我第一次运行应用程序(脚本被缓存在 firefox 上)并修改脚本并重新运行应用程序时,firefox 正在使用缓存的脚本而不是更新的脚本。

我使用的是 Firefox 3.6.13。

我已经尝试过使用 HttpHeaders,但 Firefox 似乎忽略了我的代码。

这是我的代码:

    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
    HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
    HttpContext.Current.Response.Cache.SetNoStore();

我尝试将此代码放在 global.asax > Application_BeginRequest 和 MasterPage.aspx.cs > Page_Load,但它不起作用。

提前致谢。

【问题讨论】:

  • 您是否试图阻止仅用于开发环境的缓存?如果是,您是否尝试过在工具 -> 选项 -> 隐私选项卡中将 Firefox 设置为不缓存任何内容?
  • 一个 hacky 解决方法是将查询字符串附加到您的脚本,以便 ff 认为它是新的
  • 您好,这个问题是从我的项目的生产中报告的,所以很遗憾,告诉用户将他们的 Firefox 设置为不缓存任何内容是不合适的。 :(
  • @Kael 啊,那样的话,我会删除我的评论。
  • @mrtsherman 谢谢,我已经使用了查询字符串技术,我只是在想是否还有其他选项可以解决这个问题。

标签: c# asp.net firefox caching


【解决方案1】:

一种技术是在 URL 中添加一个随机元素作为查询字符串,因此浏览器不知道如何缓存脚本:

<script src="jquery.js?<%=DateTime.Now.Ticks %>" />

最好是附加程序集的当前内部版本号,这样您就可以在脚本未更改的情况下获得脚本缓存的性能优势。但是,这只有在您从未在二进制版本中“带外”更改脚本文件时才有效。

【讨论】:

  • 嗨!感谢您的回答。 :D 我已经尝试过这个(查询字符串),它解决了缓存问题,但如果有的话,我正在寻找一种更编程的方式,比如从后面的代码中设置它。
  • 您可以始终使用来自代码隐藏的 RegisterClientScriptBlock 并添加 Ticks
  • @Magnus:我的意思是如果有任何其他选项,而不是使用我可以从后面的代码设置的查询字符串。 ^_^
【解决方案2】:

你应该可以使用

HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);

但您必须有一个 http 处理程序,将脚本直接呈现到响应流,然后将脚本标记的源 url 设置为处理程序或配置 IIS 以使用特定处理程序处理所有 javascript: 将 *.js 指向 aspnet_isapi.dll ISAPI 扩展,然后在您的 web.config 中添加以下内容

<system.web>
    <httpHandlers>
        <!-- javascript handler -->
        <add verb="*" path="*.js" 
         type="skmHttpHandlers.JavascriptHandler, skmHttpHandlers" />
    </httpHandlers>

比处理程序:

namespace skmHttpHandlers
{
   public class JavascriptHandler : IHttpHandler
   {
      public void ProcessRequest(HttpContext context)
      {
         context.Response.Clear();
         context.Response.Cache.SetCacheability(HttpCacheability.NoCache)
         using (var scriptStream = File.Open(Server.MapPath("~/script/TheScript.js"), FileMode.Open))
           scriptStream.CopyTo(context.Response.OutputStream);
         context.Response.End();
      }

      public bool IsReusable
      {
         get
         {
            return false;
         }
      }
   }
}

【讨论】:

  • 嗨!感谢您的回答。我是 HttpHandlers 的新手。我正在寻找如何使用它来渲染脚本,但没有运气。你能给我一个示例代码吗?
  • 感谢 Magnus 提供的代码。我将对此进行调查并在测试后发布我的更新。 :)
  • 嗨,我测试了这个,但 Firefox 仍然没有更新脚本。这是我的代码(我不能 100% 确定我是否做对了,但我能够使用 HttpHandler 渲染脚本)。
  • @Web.config: &lt;!-- I did a single file path only --&gt; &lt;add verb="*" path="*../Scripts/JScript.js" type="Namespace.ScriptHandler, Namespace"/&gt;
  • @ScriptHandler: context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.Cache.SetAllowResponseInBrowserHistory(false); context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1)); context.Response.Cache.SetNoStore(); string script = "&lt;script language='javascript' src='" + context.Request.ApplicationPath + "/Scripts/JScript.js'&gt;&gt;&lt;/script&gt;"; script = script.Replace("//", "/"); context.Response.Write(script);
【解决方案3】:

1) 安装 IIS 模块:http://www.iis.net/download/urlrewrite

2) 将此放在 web.config 中的部分:

 <rewrite>
    <rules>
      <rule name="Style Rewrite" stopProcessing="true">
        <match url="^v(.*?)/styles/(.*)" />
        <action type="Rewrite" url="/styles/{R:2}" />
      </rule>
      <rule name="Javascript Rewrite" stopProcessing="true">
        <match url="^v(.*?)/javascript/(.*)" />
        <action type="Rewrite" url="/javascript/{R:2}" />
      </rule>
    </rules>
  </rewrite>

3) 编写这个辅助函数(到某个全局类中)

public static string PutCSS(string filepath)
{
    FileInfo f = new FileInfo(HttpContext.Current.Server.MapPath(filepath));
    string timestamp = f.LastWriteTimeUtc.Year.ToString() + f.LastWriteTimeUtc.Month.ToString() + f.LastWriteTimeUtc.Day.ToString() + f.LastWriteTimeUtc.Hour.ToString() + f.LastWriteTimeUtc.Minute.ToString() + f.LastWriteTimeUtc.Second.ToString() + f.LastWriteTimeUtc.Millisecond.ToString();
    return "<link type=\"text/css\" rel=\"stylesheet\" href=\"v" + timestamp + "/" + filepath + "\" />\n";
}

public static string PutJS(string filepath)
{
    FileInfo f = new FileInfo(HttpContext.Current.Server.MapPath(filepath));
    string timestamp = f.LastWriteTimeUtc.Year.ToString() + f.LastWriteTimeUtc.Month.ToString() + f.LastWriteTimeUtc.Day.ToString() + f.LastWriteTimeUtc.Hour.ToString() + f.LastWriteTimeUtc.Minute.ToString() + f.LastWriteTimeUtc.Second.ToString() + f.LastWriteTimeUtc.Millisecond.ToString();
    return "<script type=\"text/javascript\" src=\"v" + timestamp + "/" + filepath + "\" ></script>\n";
}

4) 代替:

<link href="Styles/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="Javascript/userscript.js" ></script>

用途:

<%= global.PutCSS("Styles/style.css")%>
<%= global.PutCSS("Javascript/userscript.css")%>

【讨论】:

    【解决方案4】:

    如果您可以控制 IIS 配置,那么您可以将所有脚本放在一个文件夹中并告诉 IIS 立即使内容过期,或者添加您选择的其他自定义标头。

    适用于 IIS 6.0 的页面是 http://technet.microsoft.com/en-us/library/cc732442.aspx

    【讨论】:

    • 您好,我已经在 IIS 上提出了 HttpHeader 配置,但是我们在生产站点中控制 IIS 时遇到了问题。但这肯定会奏效。谢谢! :D
    【解决方案5】:
    <head runat="server">
        <%= "<link href='/asset/Style.css?v" + new Random().Next(1000,9999).ToString() + "' rel='stylesheet' />" %>
    </head>
    

    【讨论】:

      【解决方案6】:

      我想要缓存脚本和样式...仅在它们更改时重新加载它们...使用文件的日期很容易:

      <script type="text/javascript" src="~/js/custom.js?d=@(System.Text.RegularExpressions.Regex.Replace(File.GetLastWriteTime(Server.MapPath("~/js/custom.js")).ToString(),"[^0-9]", ""))"></script>
      
      
      <link rel="stylesheet" href="~/css/custom.css?d=@(System.Text.RegularExpressions.Regex.Replace(File.GetLastWriteTime(Server.MapPath("~/css/custom.css")).ToString(),"[^0-9]", ""))" />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-06
        • 2012-01-09
        • 2016-08-29
        • 2011-01-15
        • 2010-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多