先放上结论吧,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抓包:
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="jq_125bece.js"></script> <script type="text/javascript" src="errnew.js"></script> <link rel="stylesheet" href="a.css"/> <script type="text/javascript"> $(document).ready(function() { setTimeout(function(){ location.href = 'a.html?' + Date.now(); }, 10000); }); </script> </head> <body> </body> </html>
验证的结果,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(); } /// <summary> /// 更新本地资源文件,并返回是否进行了更新 /// </summary> /// <param name="url">远程资源文件地址</param> /// <param name="localFile">本地缓存资源地址</param> /// <returns></returns> 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; } /// <summary> /// 从HttpResposne中获取响应字符串 /// </summary> /// <param name="response"></param> /// <param name="encoding"></param> /// <returns></returns> 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); }
关于页面缓存的Cache-Control之no-store
附网上解释:
Cache-Control
Http1.1 中的标准,可以看成是 expires 的补充。使用的是相对时间的概念。
简单介绍下Cache-Control的属性设置。
1)max-age: 设置缓存的最大的有效时间,单位为秒(s)。max-age会覆盖掉Expires
2) s-maxage: 只用于共享缓存,比如CDN缓存(s -> share)。与max-age 的区别是:max-age用于普通缓存,
而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖max-age 和 Expires.
3) public:响应会被缓存,并且在多用户间共享。默认是public。
4) private: 响应只作为私有的缓存,不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。
5)no-cache: 指定不缓存响应,表明资源不进行缓存。但是设置了no-cache之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。因此有的时候只设置no-cache防止缓存还是不够保险,还可以加上private指令,将过期时间设为过去的时间。
6)no-store: 绝对禁止缓存。
7)must-revalidate: 如果页面过期,则去服务器进行获取。
参考浏览器缓存策略:
https://blog.csdn.net/yongche_shi/article/details/51866634
相关推荐
浏览器缓存是网络浏览的重要组成部分,它用于存储网页的静态资源,如图片、JavaScript文件、CSS样式表等,以便在用户再次访问同一页面时能够快速加载,提高网页的响应速度和用户体验。`ChromeCacheView`是一款实用的...
IE缓存是浏览器为了提高网页加载速度而存储的临时文件,这些文件通常包含了用户在浏览网页时所访问的各种资源。 ### IE缓存的工作原理 当用户访问一个网页时,IE会将页面上的图片、脚本、样式表等静态内容保存在...
浏览器缓存是互联网浏览过程中的一种常见机制,它用于存储网页上的静态资源,如图片、JavaScript文件和CSS样式表,以加快网页加载速度。当用户访问过的网页再次被打开时,浏览器会优先从本地缓存中读取这些资源,而...
3. 虽然IE缓存资源提取器专注于IE,但现代网络环境中,更多用户可能使用其他浏览器,如Chrome、Firefox等,这些浏览器的缓存管理方式和文件结构与IE有所不同,因此需要寻找对应工具。 总的来说,"废客IE缓存资源...
5. **资源大小限制**:每个浏览器对离线存储的容量都有所限制,例如,Chrome和Firefox的默认值约为50MB。开发者需注意不要超过这个限制,否则可能导致缓存失败。 总的来说,`manifest`文件是HTML5离线存储的核心,...
- **系统兼容性**:此工具可能只适用于Internet Explorer浏览器,对于其他浏览器(如Chrome、Firefox等)的缓存可能无法处理。 - **文件安全**:在提取文件时,确保电脑没有病毒或恶意软件,以免被感染。 综上所述...
浏览器缓存是网络浏览过程中非常重要的一个组成部分,它存储了我们访问过的网页的静态资源,如图片、JavaScript 文件和 CSS 样式表等,目的是为了加快网页加载速度,提高用户体验。然而,有时缓存可能会导致网页加载...
CCleaner支持多种流行浏览器的缓存清理,包括Google Chrome、Firefox、Internet Explorer、Microsoft Edge等。在使用CCleaner进行清理前,用户可以选择要清理的浏览器,并决定是否保留某些特定网站的缓存数据,以...
2. 选择“Internet选项”(对于IE浏览器)或“高级”设置(对于Chrome、Firefox等其他浏览器)。 3. 在弹出的窗口中,切换到“常规”选项卡。 4. 找到“浏览历史”或“清除浏览数据”相关的部分,取消勾选不需要删除...
它支持所有主流浏览器,包括但不限于Chrome、Firefox、Safari、Opera等,这得益于其对多种浏览器缓存格式的解析能力。对于Chrome浏览器,其使用的是名为"disk_cache"的缓存系统,VideoCache能够准确地找到这些隐藏在...
1. **浏览器缓存**:大多数网络浏览器如Chrome、Firefox和Edge都有自己的缓存系统,用于存储网页的静态资源(如图片、CSS样式表和JavaScript文件),以加快网页加载速度。清理浏览器缓存可以释放磁盘空间,并可能...
现代浏览器如Chrome、Firefox、Safari也有类似的缓存机制,管理方式也大同小异,只是菜单路径和选项略有不同。 综上所述,"IE缓存.e.rar"这个压缩包可能包含的是用户的IE浏览器缓存文件,可能用于分析浏览历史、...
同时,针对Internet Explorer、Firefox、Chrome和Safari等主流浏览器,文档分析了它们对这些缓存控制设置的响应差异,以帮助开发者更好地理解和应用这些机制。 通过IBM Mashups和开源的"Roller Weblogger"等实例,...
1. **浏览器缓存**:大多数现代浏览器如Chrome、Firefox、Safari都提供了清理缓存的选项。通常可以在设置或隐私菜单中找到。清除浏览器缓存可以释放硬盘空间,并解决因缓存问题导致的网页加载异常。 2. **操作系统...
7. **浏览器兼容性**:电商网站需要考虑不同浏览器之间的兼容性,确保在主流浏览器如Chrome、Firefox、Safari和Edge上都能正常运行。开发者可能使用如Modernizr这样的库来检测浏览器特性,或者采用polyfill技术来...
开发者可以将此自定义浏览器与其他主流浏览器(如Chrome、Firefox)进行对比测试,以验证其载入速度和用户体验。测试应涵盖不同类型的网站,包括静态HTML页面、动态Web应用以及含有大量图片和脚本的复杂页面。 总的...
"用FireFox打开,就会立即显示GIF动画图标,不需要添加到收藏夹再打开.txt"指出,Firefox是少数几个原生支持动画Favicon的浏览器之一。为了让其他浏览器如Chrome或Safari也能看到动画,可以使用HTML5的`<link>`标签...
浏览器插件项目模板是开发Chrome、Firefox等现代浏览器扩展程序的一种高效方式,它通常包括了必要的文件结构和配置,能够帮助开发者快速启动一个新的浏览器插件项目。Webpack是现代JavaScript应用程序的模块打包工具...
在实际应用中,有一些常用的HTTP抓包插件,如Chrome浏览器的开发者工具中的“Network”面板,Firefox的“Web Developer”扩展,以及第三方工具如Fiddler和Wireshark。这些工具虽然各有特色,但都能提供类似的功能,...
插件通常以扩展形式存在于浏览器中,如Chrome、Firefox等,它们可以添加或增强浏览器的功能。在这个案例中,该插件可能是通过监听用户的浏览行为,当用户访问特定平台或需要访问文档时,提供一键访问或整合来自多个...