Chrome或Firefox浏览器对静态资源文件的缓存时长是多久!

2025-06-22 19:56:06 5657

先放上结论吧,Chrome和Firefox对js、css之类的文件,在内存中的缓存时长,是: (访问时间 - 该文件的最后修改时间) ÷ 10

假设文件 a.js 最后编辑时间是 2018年12月1号 10点0分0秒;Chrome的第一次访问时间是 2018年12月1号 12点0分0秒;第一次访问与文件编辑时间相差2小时,即7200秒,那么缓存时长就是720秒 即结论如下:1、在 2018年12月1号 12点0分1秒到 12点11分59秒,这12分钟内,浏览器不会发起http请求;2、在 2018年12月1号 12点12分0秒,会发起带 If-Modified-Since 的http请求3、如果希望浏览器每次都发起http请求,请在WebServer返回Header Cache-Control: no-cache

问题的由来: 我提供了一个多语言的js资源包服务,昨天有QA反馈,后台修改了内容,前台没变化!! PC上还好办,可以按Ctrl + F5,强制刷新,手机上就不好办了,只能等着缓存过期。 而且我们也不可能主动通知用户去强制刷新吧!

问题解决很简单,在IIS的站点=》HTTP响应标头里,添加一个Header:Cache-Control,值为no-cache, 问题解决。 注意:加了这个标头后,浏览器在请求这个站点的js/css/图片资源时,每次都会重新发起HTTP连接请求,虽然请求的Header里会带上 If-Modified-Since,但是HTTP连接本身也是很耗资源的,所以要根据场景来选择性添加, 比如不添加标头,而是通过js加版本号来避免缓存。

虽然缓存问题解决了,但是如果没加标头,Chrome会在内存缓存多久啊?这个问题我搜索了一下,没有找到Chrome的资料,但是有文章说Firefox是按顶部的结论实现的,参考RFC协议关于缓存过期的部分: https://tools.ietf.org/html/rfc2616#section-13.2.4

为了验证,写了一个html定时刷新自己,然后扔在IIS站点下,然后用Chrome的F12->Network抓包:

验证的结果,Chrome也是按这个机制作为本地缓存过期策略。

文章最后,贴一段C#版本的判断304响应的代码,用于客户端更新本地资源:

static void Main(string[] args)

{

var url = "https://beinet.cn/language.js";

var localFile = @"d:\language.js";

var ret = UpdateResource(url, localFile);

Console.WriteLine("是否有更新" + ret);

ret = UpdateResource(url, localFile);

Console.WriteLine("是否有更新" + ret);

Console.Read();

}

///

/// 更新本地资源文件,并返回是否进行了更新

///

/// 远程资源文件地址

/// 本地缓存资源地址

///

static bool UpdateResource(string url, string localFile)

{

const string responseHeader = "Last-Modified";

var timeFile = localFile + responseHeader;

string lastModified = null;

if (File.Exists(timeFile))

{

lastModified = File.ReadAllText(timeFile);

}

var request = (HttpWebRequest)WebRequest.Create(url);

request.Headers.Add("Accept-Encoding", "gzip, deflate");

request.Timeout = 5000; // 默认5秒超时

request.AllowAutoRedirect = true;

if (!string.IsNullOrEmpty(lastModified))

{

request.IfModifiedSince = DateTime.Parse(lastModified); // 设置Header if-modified-since

}

string json;

HttpWebResponse response;

try

{

response = (HttpWebResponse) request.GetResponse();

}

catch (WebException exp)

{

if(exp.Response != null && ((HttpWebResponse)exp.Response).StatusCode == HttpStatusCode.NotModified)

return false;

throw;

}

using (response)

{

lastModified = response.Headers[responseHeader];

json = GetResponseString(response, Encoding.UTF8);

}

// todo: 这里要考虑判断是否json格式

SaveToFile(localFile, json);

SaveToFile(timeFile, lastModified);

return true;

}

///

/// 从HttpResposne中获取响应字符串

///

///

///

///

static string GetResponseString(HttpWebResponse response, Encoding encoding)

{

using (Stream stream = response.GetResponseStream())

{

if (stream == null)

{

return "GetResponseStream is null";

}

string str;

string contentEncoding = response.ContentEncoding.ToLower();

if (contentEncoding.Contains("gzip"))

{

using (Stream stream2 = new GZipStream(stream, CompressionMode.Decompress))

{

str = GetFromStream(stream2, encoding);

}

}

else if (contentEncoding.Contains("deflate"))

{

using (Stream stream2 = new DeflateStream(stream, CompressionMode.Decompress))

{

str = GetFromStream(stream2, encoding);

}

}

else

{

str = GetFromStream(stream, encoding);

}

return str;

}

}

static string GetFromStream(Stream stream, Encoding encoding)

{

using (StreamReader reader = new StreamReader(stream, encoding))

{

return reader.ReadToEnd();

}

}

static void SaveToFile(string targetFile, string content)

{

var now = DateTime.Now.ToString("yyyyMMddHHmmssfffffff");

// 写入临时文件,再进行移动

var tmpFile = targetFile + now;

File.WriteAllText(tmpFile, content);

if (File.Exists(targetFile))

{

var bakFile = targetFile + "bak" + now; // 备份文件

File.Move(targetFile, bakFile);

}

File.Move(tmpFile, targetFile);

}

Copyright © 2022 世界杯积分_上一届世界杯冠军 - f0cai.com All Rights Reserved.