JS使用Expires max-age判断缓存过期的浏览器实例

 更新时间:2023年11月02日 10:20:37   作者:DiracKeeko  
这篇文章主要为大家介绍了JS使用Expires max-age判断缓存过期的浏览器实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Expires (http1.0)

在HTTP Header中通过Expires字段 传递一个GMT格式的字符串。

举例:

Expires: Wed Feb 20 2019 11:25:41 GMT

Cache-Control: max-age=<seconds> (http1.1)
在HTTP Header中通过Cache-Control字段中的值max-age传递一个max-age=<seconds>的字符串。

举例:

Cache-Control: max-age=3600

如果Expires和Cache-Control: max-age=<seconds>二者同时存在,max-age 的优先级高于 expires
(浏览器会根据 max-age 指令的值来决定缓存的有效期,而忽略 Expires)

上面这段话是在中文互联网上出现的很多的内容,表述可能不一样,但是内容就是这些了。

那么浏览器到底怎么判断缓存过期?用max-age判断缓存过期是否与本地时间有关?

在中文互联网的论坛中,基本都是说Expires字段设置的缓存过期时间会受本地时间影响,max-age设置的缓存过期时间不会受本地时间影响。

max-age设置缓存后

-那么在使用max-age设置缓存后,浏览器到底怎么判断缓存过期?判断缓存过期是否与本地时间有关?

看我下面这个问题场景。

如果HTTP响应中包含以下头部:

Date: Wed, 16 Oct 2019 07:42:37 GMT
Cache-Control: max-age=3600

按照中文互联网上的常见表述

"浏览器记录下max-age的时间点是通过在HTTP响应中的Date头部来完成的。

Date头部指示了服务器响应请求的时间,它通常以格林威治标准时间 (GMT) 格式表示。"

那么浏览器会计算出资源的有效期截止时间为Wed, 16 Oct 2019 08:42:37 GMT,(即当前时间加上max-age指定的秒数) 。浏览器会记录这个时间点,以便后续请求时判断资源是否过期。

问题

当浏览器第二次发请求的时候,浏览器是否需要找到一个时间节点T2 来判定T2与 Wed, 16 Oct 2019 08:42:37 GMT的大小关系?

-如果需要T2,那么T2如何取值? (是否受本地时间的影响?)

-如果不需要T2,那么浏览器通过什么来判定这个缓存是否过期?

下面开始进入正题,查证的过程中我发现有不少(错误的)内容在中文互联网上被互相转载,站站相传,属实离谱。
本文引用材料均有出处。各位读者可以点link查看。

以chromium内核的实现为例来说明

1、判断缓存是否过期

https://github.com/chromium/chromium/blob/main/net/http/http_response_headers.cc#L1107-L1114

公式如下:

response_is_fresh = (freshness_lifetime > current_age)

这里有个字段 response_is_fresh (相应依旧新鲜)
字面理解,如果response_is_fresh为true,则表示缓存未过期。
如果保鲜时间(freshness_lifetime) 大于 当前经历时间(current_age),则表示缓存未过期。

再往下看,找到freshness_lifetime和current_age的计算方法。

2、freshness_lifetime的计算 ( 保鲜时间(有效期)的计算 )

https://github.com/chromium/chromium/blob/main/net/http/http_response_headers.cc#L1141-L1163

这段话里明确说明max-age的优先级大于expires

如果有max-age
freshness_lifetime = max_age_value

如果没有max-age
freshness_lifetime = expires_value - date_value

看1152 1153两行

Note that neither of these calculations is vulnerable to clock skew, since all of the information comes from the origin server

"注意,这两种计算方式都不会受到时钟偏差的影响,因为所有信息都来自于源服务器。"

也就是说,不论是用max-age还是expires计算freshness_lifetime,都不会受到时钟偏差的影响。

3、current_age的计算 ( 当前经历时间的计算 )

https://github.com/chromium/chromium/blob/main/net/http/http_response_headers.cc#L1264-L1332

// From RFC 7234 section 4.2.3:
//
// The following data is used for the age calculation:
//
//    age_value
//
//       The term "age_value" denotes the value of the Age header field
//       (Section 5.1), in a form appropriate for arithmetic operation; or
//       0, if not available.
//
//    date_value
//
//       The term "date_value" denotes the value of the Date header field,
//       in a form appropriate for arithmetic operations.  See Section
//       7.1.1.2 of [RFC7231] for the definition of the Date header field,
//       and for requirements regarding responses without it.
//
//    now
//
//       The term "now" means "the current value of the clock at the host
//       performing the calculation".  A host ought to use NTP ([RFC5905])
//       or some similar protocol to synchronize its clocks to Coordinated
//       Universal Time.
//
//    request_time
//
//       The current value of the clock at the host at the time the request
//       resulting in the stored response was made.
//
//    response_time
//
//       The current value of the clock at the host at the time the
//       response was received.
//
//    The age is then calculated as
//
//     apparent_age = max(0, response_time - date_value);
//     response_delay = response_time - request_time;
//     corrected_age_value = age_value + response_delay;
//     corrected_initial_age = max(apparent_age, corrected_age_value);
//     resident_time = now - response_time;
//     current_age = corrected_initial_age + resident_time;

1264行到1305行,这一段注释里的now,对应下面HttpResponseHeaders::GetCurrentAge这个方法中的current_time(L1328)

The term "now" means "the current value of the clock at the host performing the calculation". A host ought to use NTP ([RFC5905]) or some similar protocol to synchronize its clocks to Coordinated Universal Time.

关于now的注释这里写明了

"now"一词表示"执行计算的主机上时钟的当前值"。主机应该使用NTP([RFC5905])或类似协议将其时间与世界时钟同步。

那么current_age的计算是需要依赖于客户端主机的本地时钟的。

回到这个问题

如果HTTP响应中包含以下头部:

Date: Wed, 16 Oct 2019 07:42:37 GMT
Cache-Control: max-age=3600

当浏览器第二次发请求的时候,浏览器是否需要找到一个时间节点T2来判定T2与 Wed, 16 Oct 2019 08:42:37 GMT的大小关系?

-如果需要T2,那么T2如何取值? (是否受本地时间的影响?)

-如果不需要T2,那么浏览器通过什么来判定这个缓存是否过期?

总结

(chromium内核的)浏览器用的是比较freshness_lifetime(约等于max-age,保鲜时间,是一个时间跨度)和current_age(当前经历时间,也是一个时间跨度)来计算有效期。

不需要时间节点T2。

计算freshness_lifetime用的是服务器时间, 不受本地时间影响。
但计算current_age用到了本地时间(current_time, 也就是注释中的now),而且没法保证本地时间与服务器时间一致。

因此,不论是Expires还是Cache-Control: max-age=<seconds> 计算缓存有效期的时候,都会受到本地时间的影响。

以上就是JS使用Expires max-age判断缓存过期的浏览器实例的详细内容,更多关于js浏览器缓存判断的资料请关注脚本之家其它相关文章!

相关文章

  • 原生JS实现多条件筛选

    原生JS实现多条件筛选

    这篇文章主要为大家详细介绍了原生JS实现多条件筛选,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • 微信小程序开发指南之图片压缩解决方案

    微信小程序开发指南之图片压缩解决方案

    在项目开发过程中遇到一个需要从小程序上传图片的需求,此需求实现起来并不难,下面这篇文章主要给大家介绍了关于微信小程序开发指南之图片压缩解决方案的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • JavaScript数据操作_浅谈原始值和引用值的操作本质

    JavaScript数据操作_浅谈原始值和引用值的操作本质

    下面小编就为大家带来一篇JavaScript数据操作_浅谈原始值和引用值的操作本质。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • js正则表达式校验指定字符串的方法

    js正则表达式校验指定字符串的方法

    今天小编就为大家分享一篇js正则表达式校验指定字符串的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • JavaScript实现留言板实战案例

    JavaScript实现留言板实战案例

    这篇文章主要给大家介绍了关于JavaScript实现留言板的相关资料,使用JavaScript来编写留言板功能相信大家都不陌生,文中给出了详细的示例代码,需要的朋友可以参考下
    2023-07-07
  • JS移动端/H5同时选择多张图片上传并使用canvas压缩图片

    JS移动端/H5同时选择多张图片上传并使用canvas压缩图片

    这篇文章主要介绍了JS移动端/H5同时选择多张图片上传并使用canvas压缩图片,需要的朋友可以参考下
    2017-06-06
  • 浅谈JS正则表达式的RegExp对象和括号的使用

    浅谈JS正则表达式的RegExp对象和括号的使用

    下面小编就为大家带来一篇浅谈JS正则表达式的RegExp对象和括号的使用。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • 如何检测JavaScript中的死循环示例详解

    如何检测JavaScript中的死循环示例详解

    这篇文章主要给大家介绍了关于如何检测JavaScript中死循环的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • javascript实现简单下拉菜单效果

    javascript实现简单下拉菜单效果

    这篇文章主要为大家详细介绍了javascript实现简单下拉菜单效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一
    2022-08-08
  • Bootstrap Multiselect 常用组件实现代码

    Bootstrap Multiselect 常用组件实现代码

    bootstrap-multiselect插件是一款基于bootstrap的下拉框美化插件,我们一般用来请求后台返回具有label和text对象的json数组即可渲染。接下来通过本文给大家分享Bootstrap Multiselect 常用组件实现代码,感兴趣的朋友一起看看吧
    2017-07-07

最新评论