你值得了解的HTTP缓存机制(代码详解)
之前的文章《深入解析vue中路由切换白屏的问题(附代码)》中,给大家了解了vue中路由切换白屏的问题。下面本篇文章给大家了解HTTP缓存机制详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助。
Web
缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN
缓存)、浏览器缓存。
浏览器缓存也包含很多内容:HTTP
缓存、indexDB
、cookie
、localstorage
等等。
这里要说的是http
缓存。
使用缓存的好处
减少了冗余的数据传输
缓解了网络瓶颈的问题
降低了对原始服务器的要求
降低了距离时延
术语
缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。
机制
策略
1)缓存存储策略
缓存存储策略决定了客户端是否应该存储http
的response
。与缓存存储有关的http header
主要为response header
中的Cache-Control
。该header
有下面几个对应的值:Public
、Private
、no-cache
、max-age
、no-store
。除了no-store
,其它几种都会表明response
应该被客户端缓存。
指令 | 说明 |
---|---|
Public | 所有内容都将被缓存(客户端和代理服务器都可缓存) |
Private | 内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存) |
max-age = xxx (xxx is numeric) | 缓存的内容将在 xxx 秒后失效,失效前可以直接使用本地缓存,失效后必须向服务器确认资源是否已经改变。 |
no-store | 完全不在客户端缓存 |
no-cache | 可以认为等同于 max-age=0 的情况,即将 response 缓存在客户端,但是之后每次都向服务器确认资源是否已经改变 |
通过Cache-Control:Public
设置我们可以将HTTP
响应数据存储到本地,但此时并不意味着后续浏览器会直接从缓存中读取数据并使用, 因为它无法确定本地缓存的数据是否可用(可能已经失效),需通过缓存过期策略来判断
2)缓存过期策略
缓存过期策略决定了客户端存储在本地的缓存数据是否已过期,如未过期则可以直接使用本地存储的数据,否则就需要发请求到服务端尝试重新获取数据。 与缓存过期策略有关的http header 为Expires
。
Expires
表示缓存数据有效的绝对时间,告诉客户端到了这个时间点后本地缓存就失效了,在这个时间内客户端可以不请求服务器而直接从本地缓存中使用已存储的结果。
需要注意的是:no-cache和max-age=xxx
的优先级高于Expires
,当它们同时存在的时候,后者会被覆盖掉。其次, 缓存数据过期只是告诉客户端不能再直接从本地读取缓存了,而是需要再发一次请求到服务器去确认。具体什么情况下本地存储的数据还可以继续使用就与缓存对比策略有关了。
3)缓存对比策略
将缓存在客户端的数据标识发往服务端,服务端通过标识来判断客户端缓存数据是否仍有效,进而决定是否要重发数据。客户端检测到数据过期或浏览器刷新后,会重新发起一个 http 请求到服务器,服务器此时并不急于返回数据,而是看请求头有没有带标识(If-Modified-Since、If-None-Match
)过来,如果判断标识仍然有效,则返回304
告诉客户端取本地缓存数据来用即可(这里要注意的是你必须要在首次响应时输出相应的头信息(Last-Modified、ETags
)到客户端)。 本地缓存数据即使被认为过期,并不等于数据从此就没用了。
缓存过期取值
存储策略里面no-cache
等同于max-age=0
,假如服务端返回的响应中没有指明max-age
、no-cache
或Expires
时,客户端是否会缓存 http response
呢 ?通过Fiddler
、Charles
等抓包工具可以发现,客户端一样会进行缓存
其取值值为响应头中的Date
与Last-Modified
之间的差值的10%作为缓存有效时间
在Fiddler
的Caching
面板中可以看到
HTTP/1.1 Cache-Control Header is present: private HTTP Last-Modified Header is present: Tue, 08 Nov 2016 06:59:00 GMT No explicit HTTP Cache Lifetime information was provided. Heuristic expiration policies suggest defaulting to: 10% of the delta between Last-Modified and Date. That's '05:15:02' so this response will heuristically expire 2016/11/11 0:46:01.
用一副图来表示
缓存的控制
1)强制缓存
可以通过Expires
,Cache-Control
来设定,Expires
指缓存过期的时间,超过了这个时间点就代表资源过期。有一个问题是由于使用具体时间,如果时间表示出错或者没有转换到正确的时区都可能造成缓存生命周期出错。
并且Expires
是HTTP/1.0
的标准,现在更倾向于用HTTP/1.1
中定义的Cache-Control
。两个同时存在时也是Cache-Control
的优先级更高。
2)协商缓存
缓存的资源到期了,并不意味着资源内容发生了改变,如果和服务器上的资源没有差异,实际上没有必要再次请求。客户端和服务器端通过某种验证机制验证当前请求资源是否可以使用缓存。 浏览器第一次请求数据之后会将数据和响应头部的缓存标识存储起来。再次请求时会带上存储的头部字段,服务器端验证是否可用。如果返回304 Not Modified
,代表资源没有发生改变可以使用缓存的数据,获取新的过期时间。反之返回200
就相当于重新请求了一遍资源并替换旧资源。
Last-modified/If-Modified-Since
Last-modified:
服务器端资源的最后修改时间,响应头部会带上这个标识。第一次请求之后,浏览器记录这个时间,再次请求时,请求头部带上If-Modified-Since
即为之前记录下的时间。服务器端收到带If-Modified-Since
的请求后会去和资源的最后修改时间对比。若修改过就返回最新资源,状态码200
,若没有修改过则返回304
。
Etag/If-None-Match
由服务器端上生成的一段hash
字符串,第一次请求时响应头带上ETag: abcd
,之后的请求中带上If-None-Match: abcd
,服务器检查ETag
,返回304
或200
。
关于 last-modified 和 Etag 区别
某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新。
Last-modified
只能精确到秒。一些资源的最后修改时间改变了,但是内容没改变,使用
Last-modified
看不出内容没有改变。Etag
的精度比Last-modified
高,属于强验证,要求资源字节级别的一致,优先级高。如果服务器端有提供ETag
的话,必须先对ETag
进行Conditional Request
。
注意:实际使用ETag/Last-modified
要注意保持一致性,做负载均衡和反向代理的话可能会出现不一致的情况。计算ETag
也是需要占用资源的,如果修改不是过于频繁,看自己的需求用Cache-Control
是否可以满足。
实际应用
首先要明确哪些内容适合被缓存哪些不适合。
考虑缓存的内容:css
样式文件,js
文件,logo
、图标,html
文件,可以下载的内容一些不应该被缓存的内容:业务敏感的GET请求
可缓存的内容又分为几种不同的情况:
不经常改变的文件:给max-age
设置一个较大的值,一般设置max-age=31536000
比如引入的一些第三方文件、打包出来的带有hash
后缀css
、js
文件。一般来说文件内容改变了,会更新版本号、hash
值,相当于请求另一个文件。 标准中规定max-age
的值最大不超过一年,所以设成max-age=31536000
。至于过期内容,缓存区会将一段时间没有使用的文件删除掉。
[完]
推荐学习:Html5视频教程
以上是你值得了解的HTTP缓存机制(代码详解)的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

PHP与Vue:完美搭档的前端开发利器在当今互联网高速发展的时代,前端开发变得愈发重要。随着用户对网站和应用的体验要求越来越高,前端开发人员需要使用更加高效和灵活的工具来创建响应式和交互式的界面。PHP和Vue.js作为前端开发领域的两个重要技术,搭配起来可以称得上是完美的利器。本文将探讨PHP和Vue的结合,以及详细的代码示例,帮助读者更好地理解和应用这两

掌握HTTP301状态码的含义:网页重定向的常见应用场景随着互联网的迅猛发展,人们对网页交互的要求也越来越高。在网页设计领域,网页重定向是一种常见且重要的技术,通过HTTP301状态码来实现。本文将探讨HTTP301状态码的含义以及在网页重定向中的常见应用场景。HTTP301状态码是指永久重定向(PermanentRedirect)。当服务器接收到客户端发

在前端开发面试中,常见问题涵盖广泛,包括HTML/CSS基础、JavaScript基础、框架和库、项目经验、算法和数据结构、性能优化、跨域请求、前端工程化、设计模式以及新技术和趋势。面试官的问题旨在评估候选人的技术技能、项目经验以及对行业趋势的理解。因此,应试者应充分准备这些方面,以展现自己的能力和专业知识。

Django是一个Python编写的web应用框架,它强调快速开发和干净方法。尽管Django是一个web框架,但是要回答Django是前端还是后端这个问题,需要深入理解前后端的概念。前端是指用户直接和交互的界面,后端是指服务器端的程序,他们通过HTTP协议进行数据的交互。在前端和后端分离的情况下,前后端程序可以独立开发,分别实现业务逻辑和交互效果,数据的交

如何在C++中实现HTTP流传输?使用Boost.Asio和asiohttps客户端库创建SSL流套接字。连接到服务器并发送HTTP请求。接收HTTP响应头并打印它们。接收HTTP响应正文并打印它。

HTTP请求超时,服务器端常常会返回504GatewayTimeout状态码。该状态码表示服务器在执行某个请求时,经过一段时间后仍未能获取到请求所需的资源或完成请求的处理。它是5xx系列的状态码,表示服务器端遇到了临时的问题或过载,导致无法正确处理客户端的请求。在HTTP协议中,各种状态码都有特定的含义和用途,而504状态码则用于表示请求超时问题。在客户

Go语言作为一种快速、高效的编程语言,在后端开发领域广受欢迎。然而,很少有人将Go语言与前端开发联系起来。事实上,使用Go语言进行前端开发不仅可以提高效率,还能为开发者带来全新的视野。本文将探讨使用Go语言进行前端开发的可能性,并提供具体的代码示例,帮助读者更好地了解这一领域。在传统的前端开发中,通常会使用JavaScript、HTML和CSS来构建用户界面

Golang与前端技术结合:探讨Golang如何在前端领域发挥作用,需要具体代码示例随着互联网和移动应用的快速发展,前端技术也愈发重要。而在这个领域中,Golang作为一门强大的后端编程语言,也可以发挥重要作用。本文将探讨Golang如何与前端技术结合,以及通过具体的代码示例来展示其在前端领域的潜力。Golang在前端领域的作用作为一门高效、简洁且易于学习的
