Prevent scripts from being cached programmatically

2019-03-01 01:17发布

I would like to ask if there is a way to prevent Firefox from caching scripts (.js files).

I have a project (ASP.Net Web App) with caching issue on firefox. When I first run the application (script is being cached on firefox) and modify the script and rerun the application, firefox is using the cached script instead of the updated one.

I'm using Firefox 3.6.13.

I already tried using HttpHeaders but it seems like firefox is ignoring my codes.

Here is my code:

    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();

I tried placing this code at global.asax > Application_BeginRequest and at MasterPage.aspx.cs > Page_Load, but it isn't working.

Thanks in advance.

6条回答
爷、活的狠高调
2楼-- · 2019-03-01 01:21

You should be able to use

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

but you will have to have a http handler that renders the script directly to the response stream and than set the source url of the script tag to the handler or configure IIS to handle all javascripts using a specific handler: Point *.js to the aspnet_isapi.dll ISAPI Extension and than add the following in your web.config

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

And than the handler:

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;
         }
      }
   }
}
查看更多
祖国的老花朵
3楼-- · 2019-03-01 01:21

One technique is to add a random element to the URL as a querystring, so the browser doesn't know how to cache the script:

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

Even better would be to append the current build number of your assembly, so you get the performance benefits of script caching while the script hasn't changed. This only works however, if you never change your script files "out of band" with your binary releases.

查看更多
▲ chillily
4楼-- · 2019-03-01 01:24

1) Install IIS module: http://www.iis.net/download/urlrewrite

2) Put this in web.config into section:

 <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) Write this helper function (into some global class)

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) Instead of:

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

Use:

<%= global.PutCSS("Styles/style.css")%>
<%= global.PutCSS("Javascript/userscript.css")%>
查看更多
女痞
5楼-- · 2019-03-01 01:30

I WANT the scripts and the styles to be cached... only reload them when they change... It is easy using the date of the file:

<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]", ""))" />
查看更多
小情绪 Triste *
6楼-- · 2019-03-01 01:37
<head runat="server">
    <%= "<link href='/asset/Style.css?v" + new Random().Next(1000,9999).ToString() + "' rel='stylesheet' />" %>
</head>
查看更多
聊天终结者
7楼-- · 2019-03-01 01:43

If you have control over the IIS configuration then you can put all your scripts inside one folder and tell IIS to expire the content immediately, or add other custom headers of your choice.

The appropriate page for IIS 6.0 is http://technet.microsoft.com/en-us/library/cc732442.aspx

查看更多
登录 后发表回答