总结一下,最近项目开发遇到的。由于缓存框架设计时,缓存请求文件时只以发起请求的url 为key,导致在客户端发起url 相同,传参类型不同的请求时,交替请求会出现,带上一次请求返回的etag ,进行下次请求,服务器每次比对etag 都是上次的,所以每次请求都是200,导致缓存没有效果。

HTTP状态码304

我们经常会看到请求地址中状态存在304,如果客户端(浏览器)发送的是一个条件验证请求,则web服务器可能会返回304响应,这就表明了客户端中所请求资源的缓存仍然是有效的,也就是说该资源从上次缓存到现在没有被修改过,浏览器会自动识别并读取缓存中的文件来显示。

在进行条件请求时,一般请求头会带上 If-Modified-Since、 If-None-Match,这两个值分别对应响应头 Last-Modified、 ETag 返回的值


服务器会读取到这两个请求头中的值,判断出客户端缓存的资源是否是最新的,如果是的话,服务器就会返回304 Not Modified响应,客户端收到304响应后,就会从缓存中读取对应的资源.

另一种情况是,如果服务器认为客户端缓存的资源已经过期了,那么服务器就会返回200 OK响应,响应体就是该资源当前最新的内容.客户端收到200响应后,就会用新的资源覆盖掉旧的缓存资源.

只有在客户端缓存了对应资源且该资源的响应头中包含了Last-Modified或ETag的情况下,才可能发送条件请求.如果这两个头都不存在,则必须无条件请求该资源,服务器也就必须返回完整的资源数据.

判断是否缓存过期

主要的方式有两种,这两种都是设定请求头中的某一个字段来实现的:1、Expires;2、Cache-Control。Cache-Control设置后优先级比Expires高,先说下通过Cache-Control来控制缓存。

Cache-Control:max-age =86400;如果在请求头中设定了

那么在86400s内,如果再去请求这个文件的话,是不会发起请求的。因为还没有过期呢!唯一例外是如果这个文件是你在浏览器地址栏输入的地址来请求的(比如你请求http://www.runoob.com/wp-content/themes/runoob/assets/js/hl/prettify.css),当你刷新的时候就会让当前的这个文件所设定的过期时间失效,直接去请求服务器来看是返回个304还是返回新文件。一般这么请求的都是我们常说的入口文件(例如index.html),入口文件一刷新就会重新向服务器请求,但是入口文件里面所引入的文件如js,css等不会随着刷新而另过期时间失效。除非你单找出来那个引入链接,通过浏览器地址栏去查询它并刷新

判断文件变动
常用的方式为Etag(一般是文件的MD5值)和Last-Modified,思路上差不多,这里只介绍Last-Modified的用法。

Last-Modified方式需要用到两个字段:Last-Modified 和 if-modified-since。
先来看下这两个字段的形式:

Last-Modified:

Sat, 28 Oct 2017 06:01:34 GMT

If-Modified-Since:

Sat, 28 Oct 2017 06:01:34 GMT

当第一次请求某一个文件的时候,就会传递回来一个Last-Modified 字段,其内容是这个文件的修改时间。当这个文件缓存过期,浏览器又向服务器请求这个文件的时候,会自动带一个请求头字段If-Modified-Since,其值是上一次传递过来的Last-Modified的值,拿这个值去和服务器中现在这个文件的最后修改时间做对比,如果相等,那么就不会重新拉取这个文件了,返回304让浏览器读过期缓存。如果不相等就重新拉取。

ETag 是 Entity Tag(实体标签)的缩写

在HTTP1.1协议中其实就是请求HEAD中的一个属性

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close

ETag是HTTP1.1中才加入的一个属性,用来帮助服务器控制Web端的缓存验证。

它的原理是这样的,当浏览器请求服务器的某项资源(A)时, 服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并通过 ETag 返回给浏览器,浏览器把"3f80f-1b6-3e1cb03b" 和 A 同时缓存在本地,当下次再次向服务器请求A时,会通过类似 If-None-Match: “3f80f-1b6-3e1cb03b” 的请求头把ETag发送给服务器,服务器再次计算A的哈希值并和浏览器返回的值做比较,如果发现A发生了变化就把A返回给浏览器(200),如果发现A没有变化就给浏览器返回一个304未修改。

这样通过控制浏览器端的缓存,可以节省服务器的带宽,因为服务器不需要每次都把全量数据返回给客户端。

通常情况下,ETag更类似于资源指纹(fingerprints),如果资源发生变化了就会生成一个新的指纹,这样可以快速的比较资源的变化。在服务器端实现中,很多情况下并不会用哈希来计算ETag,这会严重浪费服务器端资源,很多网站默认是禁用ETag的。有些情况下,可以把ETag退化,比如通过资源的版本或者修改时间来生成ETag。

如果通过资源修改时间来生成ETag,那么效果和HTTP协议里面的另外一个控制属性(Last-Modified)就雷同了,使用 Last-Modified 的问题在于它的精度在秒(s)的级别,比较适合不太敏感的静态资源。

如果你也热衷技术欢迎加群一起进步:230274309 。 一起分享,一起进步!少划水,多晒干货!!欢迎大家!!!(进群潜水者勿加)

点击链接加入群聊【编程之美】:https://jq.qq.com/?_wv=1027&k=h75BfFCg

或者扫码

HTTP状态码304与ETag详解相关推荐

  1. 返回状态码304 Not Modified详解

    第一次访问 200 鼠标点击二次访问 (Cache) 按F5刷新 304 按Ctrl+F5强制刷新 200 在客户端向服务端发送http请求时,若返回状态码为304 Not Modified 则表明此 ...

  2. 服务器请求状态码返回400,HTTP详解(四)——返回结果的HTTP状态码

    HTTP状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 状态码告知从服务器端返回的请求结果 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结 ...

  3. HTTP 状态码 301 和 302 详解及区别——辛酸的探索之路

    转自:http://blog.csdn.net/grandpang/article/details/47448395 一直对http状态码301和302的理解比较模糊,在遇到实际的问题和翻阅各种资料了 ...

  4. http状态码301和302详解及区别——辛酸的探索之路

    一直对http状态码301和302的理解比较模糊,在遇到实际的问题和翻阅各种资料了解后,算是有了一定的理解.这里记录下,希望能有新的认识.大家也共勉. 官方的比较简洁的说明: 301 redirect ...

  5. http状态码301和302详解及区别

    一直对http状态码301和302的理解比较模糊,在遇到实际的问题和翻阅各种资料了解后,算是有了一定的理解.这里记录下,希望能有新的认识.大家也共勉. 官方的比较简洁的说明: ​ 301 redire ...

  6. 304 Not Modified详解

    第一次访问 200  鼠标点击二次访问 (Cache)  按F5刷新 304  按Ctrl+F5强制刷新 200 在客户端向服务端发送http请求时,若返回状态码为304 Not Modified 则 ...

  7. React 源码系列 | React Context 详解

    目前来看 Context 是一个非常强大但是很多时候不会直接使用的 api.大多数项目不会直接使用 createContext 然后向下面传递数据,而是采用第三方库(react-redux). 想想项 ...

  8. git连接远程仓库码云及命令详解

    git连接远程仓库码云及命令详解 1.前言 2.码云远程仓库(github同理) 1.注册码云账号 2.新建仓库 3.git工具的安装配置 1.git 工具下载配置 2.SHH公钥配对 4.创建 gi ...

  9. 协商缓存与状态码304

    协商缓存与状态码304 304 有时候我们访问某些网站会发现在控制台中,网络状态码返回的是304.(更多状态码相关-http必备知识点:http请求与js及状态码) 304(Not Modified) ...

最新文章

  1. poj2175费用流消圈算法
  2. 360 开源企业级 Kubernetes 多集群管理平台 Wayne
  3. 2019-05-30启动redis 后台服务运行·
  4. Android MVC模式
  5. python知识点汇总_Python知识点总结大全(一)
  6. [react] 使用高阶组件(HOC)实现一个loading组件
  7. 数据结构php语言,PHP语言做网页开发,会用到什么数据结构,算法?
  8. 【数据库】Mysql函数DATE_ADD() 增加日期/时间
  9. python正确的输入语句_Python If语句If输入是某个字符串
  10. 【数据库系统设计】关系数据库标准语言SQL(2)
  11. 阿里双十一 5 大招式!
  12. CCF201612-1 中间数(100分)【序列处理+排序】
  13. 计算机的组成 —— 显示器
  14. vue 大屏滚动实现 利用marquee和element-ui table
  15. VC程序运行时间测试
  16. PHP 中 json_encode中文处理、urlencode方法、post中文乱码
  17. Vulnstack红日安全内网域渗透靶场1实战
  18. 【内网穿透笔记】NAPT类型测试与XTCP点对点内网穿透适用例外
  19. 坦克大战之继承的实现
  20. 永劫无间游戏设计之上瘾

热门文章

  1. 高斯函数半高宽FWHM、拐点差值绝对值一半以及标准差σ的关系
  2. 合金装备幸存官网服务器维修,合金装备幸存联机要注意什么_联机注意事项分享_3DM单机...
  3. 权限 授权之 - License
  4. 找出1000以内的完数Java
  5. shell脚本之脚本案例
  6. android 颜色值16进制转换int类型;
  7. python mysql 插入_Python向MySQL插入数据
  8. 手把手教你用视频做闪屏页
  9. 第2章 GIS空间分析的基本理论
  10. 【python】点坐标旋转