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浏览器缓存判断的资料请关注脚本之家其它相关文章!

相关文章

  • javascript中闭包概念与用法深入理解

    javascript中闭包概念与用法深入理解

    这篇文章主要介绍了javascript中闭包概念与用法,结合实例形式深入分析了javascript中闭包的概念、使用方法与相关注意事项,需要的朋友可以参考下
    2016-12-12
  • 详细聊聊闭包在js中充当着什么角色

    详细聊聊闭包在js中充当着什么角色

    在js中,闭包是一个很重要又相当不容易完全理解的要点,下面这篇文章主要给大家介绍了关于闭包在js中充当着什么角色的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • D3.js 从P元素的创建开始(显示可加载数据)

    D3.js 从P元素的创建开始(显示可加载数据)

    D3是一个基于数据操作的可视化js库,认识d3,就从最基础的显示可加载数据谈起,需要的朋友可以参考下
    2014-10-10
  • 将json转换成struts参数的方法

    将json转换成struts参数的方法

    下面小编就为大家带来一篇将json转换成struts参数的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • 防止Layui form表单重复提交的实现方法

    防止Layui form表单重复提交的实现方法

    今天小编就为大家分享一篇防止Layui form表单重复提交的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • javascript实现类似百度分享功能的方法

    javascript实现类似百度分享功能的方法

    这篇文章主要介绍了javascript实现类似百度分享功能的方法,以实例形式较为完整的分析了基于javascript实现百度分享功能所涉及的样式与分享功能实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • ES6中Iterator与for..of..遍历用法分析

    ES6中Iterator与for..of..遍历用法分析

    这篇文章主要介绍了ES6中Iterator与for..of..遍历用法,结合实例形式分析了ES6中Iterator的概念、用法及for..of..遍历的使用技巧,需要的朋友可以参考下
    2017-03-03
  • document节点对象的获取方式示例介绍

    document节点对象的获取方式示例介绍

    如果要操作一个元素,首先要获取到它,下面为大家介绍下document节点对象的获取方式,感兴趣的朋友不要错过
    2013-12-12
  • JS实现简单拖拽效果

    JS实现简单拖拽效果

    这篇文章主要为大家详细介绍了JS实现拖拽效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • 在线编辑器的实现原理(兼容IE和FireFox)

    在线编辑器的实现原理(兼容IE和FireFox)

    在线编辑器的实现原理(兼容IE和FireFox)...
    2007-03-03

最新评论