- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章透过浏览器看HTTP缓存由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
作为前端开发人员,对于我们的站点或应用的缓存机制我们能做的似乎不多,但这些却是与我们关注的性能息息相关的部分,站点没有做任何缓存机制,我们的页面可能会因为资源的下载和渲染变得很慢,但大家都知道去找前端去解决页面慢的问题而不会去找服务端的开发人员。因此,了解相关的缓存机制和充分的利用它似乎就变得必不可少.
web端的缓存机制其实有多种,我在这里只是学习和整理了以浏览器为载体的HTTP缓存机制,看看它是如何工作的.
。
1.1 数据库缓存 。
我们可能听说过memcached,它就是一种数据库层面的缓存方案。数据库缓存是指,当web应用的关系比较复杂,数据库中的表很多的时候,如果频繁进行数据库查询,很容易导致数据库不堪重荷。为了提供查询的性能,将查询后的数据放到内存中进行缓存,下次查询时,直接从内存缓存直接返回,提供响应效率.
1.2 CDN缓存 。
CDN缓存一般是由网站管理员自己部署,为了让他们的网站更容易扩展并获得更好的性能。通常情况下,浏览器先向CDN网关发起Web请求,网关服务器后面对应着一台或多台负载均衡源服务器,会根据它们的负载请求,动态将请求转发到合适的源服务器上。从浏览器角度来看,整个CDN就是一个源服务器,从这个层面来说,浏览器和服务器之间的缓存机制,在这种架构下同样适用.
1.3 代理服务器缓存 。
代理服务器是浏览器和源服务器之间的中间服务器,浏览器先向这个中间服务器发起Web请求,经过处理后(比如权限验证,缓存匹配等),再将请求转发到源服务器。代理服务器缓存的运作原理跟浏览器的运作原理差不多,只是规模更大.
1.4 浏览器缓存 。
每个浏览器都实现了 HTTP 缓存,我们通过浏览器使用HTTP协议与服务器交互的时候,浏览器就会根据一套与服务器约定的规则进行缓存工作.
1.5 应用层缓存 。
应用层缓存是指我们在代码层面上做的缓存。通过代码逻辑,把曾经请求过的数据或资源等,缓存起来,再次需要数据时通过逻辑上的处理选择可用的缓存的数据.
。
我们知道通过HTTP协议,在客户端和浏览器建立连接时需要消耗时间,而大的响应需要在客户端和服务器之间进行多次往返通信才能获得完整的响应,这拖延了浏览器可以使用和处理内容的时间。这就增加了访问服务器的数据和资源的成本,因此利用浏览器的缓存机制重用以前获取的数据就变成了性能优化时需要考虑的事情.
那么有什么建议吗?当然.
为每个资源指定一个明确的缓存策略,用以定义资源是否可以缓存,由谁来缓存,可以缓存多久,并且在缓存时间到期时如何有效地重新验证。当服务器返回一个响应时,它需要在响应头中提供Cache-Control和ETag.
说到浏览器中的缓存机制,其实就相当于HTTP协议定义的缓存机制,因为浏览器为我们实现了它。一般情况下我们会想到到HTTP响应头中的Expires,Cache-Control,Last-Modified.If-Modified-Since,Etag这样的与缓存相关的响应头信息.
但是这里我们说服务器返回一个响应时提供必要的Cache-Control和Etag即可。这是为什么呢?
因为Cache-Control与Expires的作用一致,Last-Modified与ETag的作用也相近。但它们有以下区别:
现在默认浏览器均默认使用HTTP 1.1,所以Expires和Last-Modified的作用基本可以忽略,具备Cache-Control和Etag即可.
当然用户的行为也会影响浏览器的缓存,像这样:
但我们先不考虑用户的操作的影响,来看看服务器提供Cache-Control和ETag响应头来进行的缓存是如何工作的.
。
通常情况下,请求一个资源的过程大概是这样的:
我在 再看Ajax 中整理了HTTP请求的请求头和响应头的一些参数,这里就看下Etag的作用.
3.1 Etag的主要作用 。
服务器通过 ETag HTTP 头传递验证码,大概是像‘‘x123cef’’这样的字符串。当浏览器在资源过期后再次请求时,浏览器默认会通过If-None-Match传递Etag的验证码,通过验证码可以进行高效的资源更新检查:如果资源未更改,则不会传输任何数据.
Etag就主要用来在响应过期之后,验证资源是否被修改.
3.2 Etag的工作原理 。
如上图,服务器在第一次返回响应的时候设置了缓存的时间120s,假设浏览器在这120s经过之后再次请求服务器相同的资源,首先,浏览器会检查本地缓存并找到之前的响应,不幸的是,这个响应现在已经’过期’,无法在使用。此时,浏览器也可以直接发出新请求,获取新的完整响应,但是这样做效率较低,因为如果资源未被更改过,我们就没有理由再去下载与缓存中已有的完全相同的字节.
于是就到了Etag发挥作用的时候了,通常服务器生成并返回在Etag中的验证码,常常是文件内容的哈希值或者某个其他指纹码。客户端不必了解指纹码是如何生成的,只需要在下一个请求中将其发送给服务器(浏览器默认会添加):如果指纹码仍然一致,说明资源未被修改,服务器会反悔304 Not Modified,这样我们就可以跳过下载,利用已经缓存了的资源,并且该资源会继续缓存120s。就像这样:
。
服务器响应浏览器请求时响应头中的Cache-Control响应头使得每个资源都可以通过 Cache-Control HTTP 头来定义自己的缓存策略,Cache-Control 指令用来告诉我们,那个资源在什么条件下可以缓存,以及可以缓存多久.
4.1 Cache-Control头参数的含义(响应头中的Cache-Control) 。
1 no-cache : 表示必须先与服务器确认返回的响应是否被更改,然后才能使用该响应来满足后续对同一个网址的请求。因此,如果存在合适的验证令牌 (ETag),no-cache 会发起往返通信来验证缓存的响应,如果资源未被更改,可以避免下载.
2 no-store : 禁止缓存任何响应,也就是说每次用户请求资源时,都会向服务器发送一个请求,每次都会下载完整的响应.
3 public : 如果响应被标记为public,即使有关联的 HTTP 认证,甚至响应状态码无法正常缓存,响应也可以被缓存.
4 private : 浏览器可以缓存private响应,但是通常只为单个用户缓存,因此,不允许任何代理服务器对其进行缓存 。比如,用户浏览器可以缓存包含用户私人信息的 HTML 网页,但是 CDN 不能缓存.
5 max-age : 用来设置资源被缓存的最长时间(单位是秒).
4.2 如何使用Cache-Control 。
通常,我们可以通过下图的流程来设置合适的响应头的Cache-Control头.
。
一般情况下,浏览器发出的所有 HTTP 请求会首先被路由到浏览器的缓存,以查看是否缓存了可以用于实现请求的有效响应。如果有匹配的响应,会直接从缓存中读取响应,这样就避免了网络延迟以及传输产生的数据成本。然而,如果我们希望更新或废弃已缓存的响应,该怎么办?
假设我们已经告诉访问者某个 CSS 样式表缓存长达 24 小时 (max-age=86400),但是设计人员刚刚提交了一个更新,我们希望所有用户都能使用。我们该如何通知所有访问者缓存的 CSS 副本已过时,需要更新缓存?
实际上以前没有请求过该资源的新的用户会得到更新的资源,但是请求过资源的用户将在过期时间达到之前一直得到旧的被缓存的资源,直到他手动的去清理了浏览器的缓存。手动清理浏览器缓存这种事可能只有程序员才会做,那么我们要怎么做才能让用户得到更新后的资源呢?
其实很简单,我们可以在资源的内容更改后,更改资源的网址,强制用户下载新响应。比如在资源链接后添加参数:
。
我在浏览资料的时候发现了一个caching checklist,比较具有参考价值,我们可以遵循建议合理的利用缓存机制:
1 使用一致的网址:如果在不同的网址上提供相同的内容,那么将会多次获取和存储相同的内容。提示:网址是区分大小写的! 。
2 确保服务器提供验证码 (ETag):通过验证码,如果服务器上的资源未被更改,就不必传输相同的字节.
3 确定代理缓存可以缓存哪些资源:对所有用户的响应完全相同的资源很适合由 CDN 或其他代理缓存进行缓存.
4 确定每个资源的最优缓存周期:不同的资源可能有不同的更新要求。审查并确定每个资源适合的 max-age.
5 确定网站的最佳缓存层级:对 HTML 文档组合使用包含内容指纹码的资源网址以及短时间或 no-cache 的生命周期,可以控制客户端获取更新的速度.
6 变动最小化:有些资源的更新比其他资源频繁。如果资源的特定部分(例如 JavaScript 函数或一组 CSS 样式)会经常更新,应考虑将其代码作为单独的文件提供。这样,每次获取更新时,剩余内容(例如不会频繁更新的库代码)可以从缓存中获取,确保下载的内容量最少.
原文地址:https://mp.weixin.qq.com/s/4wMbVNBRm8Gh0HUaXNxfiw 。
最后此篇关于透过浏览器看HTTP缓存的文章就讲到这里了,如果你想了解更多关于透过浏览器看HTTP缓存的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
据我了解,HTTP POST 请求的正文大小没有限制。因此,客户端可能会在一个 HTTP 请求中发送 千兆字节 的数据。现在我想知道 HTTP 服务器应该如何处理此类请求。 Tomcat 和 Jett
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
假设我有一个负载均衡器,然后是 2 个 Web 服务器,然后是一个负载均衡器,然后是 4 个应用程序服务器。 HTTP 响应是否遵循与 HTTP 请求服务相同的路径? 最佳答案 按路径,我假设您是网络
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
是否有特定的(或约定的)HTTP 响应消息(或除断开连接之外的其他操作)来阐明服务器不接受 pipelined HTTP requests ? 我正在寻找能让客户端停止流水线化它的请求并分别发送每个请
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我使用 Mule 作为 REST API AMQP。我必须发送自定义请求方法:“PRINT”,但我收到: Status Code: 400 Bad Request The request could
我需要针对具有不同 HTTP 响应代码的 URL 测试我的脚本。我如何获取响应代码 300、303 或 307 等的示例/示例现有 URL? 谢谢! 最佳答案 您可以使用 httpbin为此目的。 例
我正在尝试编写一个程序来匹配 HTTP 请求及其相应的响应。似乎在大多数情况下一切都运行良好(当传输完全有序时,即使不是,通过使用 TCP 序列号)。 我发现的唯一问题是当我有流水线请求时。在那之后,
RESTful Web Services鼓励使用 HTTP 303将客户端重定向到资源的规范表示。它仅在 HTTP GET 的上下文中讨论主题。 这是否也适用于其他 HTTP 方法?如果客户端尝试对非
当使用chunked HTTP传输编码时,为什么服务器需要同时写出chunk的字节大小并且后续的chunk数据以CRLF结尾? 这不会使发送二进制数据“CRLF-unclean”和方法有点多余吗? 如
这个问题在这里已经有了答案: Is it acceptable for a server to send a HTTP response before the entire request has
如果我向同一台服务器发出多个 HTTP Get 请求并收到每个请求的 HTTP 200 OK 响应,我如何使用 Wireshark 判断哪个请求映射到哪个响应? 目前看起来像是发出了一个 http 请
func main() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r http.Request
我找不到有值(value)的 NodeJS with Typescript 教程,所以我在无指导下潜入水中,果然我有一个问题。 我不明白这两行之间的区别: import * as http from
问一个关于Are HTTP headers case-sensitive?的问题,如果 HTTP 方法区分大小写,大多数服务器如何处理“get”或“post”与“GET”或“POST”? 例如,看起来
我正在使用ASP.NET,在其中我通过动词GET接收查询,该应用程序专用于该URL。 该代码有效,但是如果用户发送的密码使http 200无效,请回答我,并在消息的正文中显示“Fail user or
Closed. This question needs details or clarity。它当前不接受答案。 想改善这个问题吗?添加详细信息,并通过editing this post阐明问题。 9
我是一名优秀的程序员,十分优秀!