前端--详解浏览器工作原理之HTTP请求

一次完整的http服务过程

当我们在浏览器中输入www.baidu.com后,具体发生了什么?

  • 对www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址
  • 根据IP地址,找到对应的服务器,发起TCP三次握手
  • 建立TCP连接后发起HTTP请求
  • 服务器响应HTTP请求,浏览器得到html代码
  • 浏览器解析html代码,并请求html代码中的资源(js、css、img等)
  • 浏览器对页面进行渲染
  • 服务器关闭TCP连接

(1)DNS解析域名的过程?
采用递归查询的方式,先找本地DNS缓存,找不到就找根域名服务器(com),根域名服务器去找下一级(baidu.com),这里,根域名服务器只是告诉本地服务器要去找baidu.com,然后由本地服务器请求baidu.com这一级服务器,如此递归查询到www.baidu.com,每次请求都是本地服务器发起的,而不是主机。

详细的过程:

  • 首先搜索浏览器自身DNS缓存(缓存时间比较短,1分钟左右,且缓存容量很小)
  • 浏览器缓存中没有,会搜索操作系统的DNS缓存
  • 操作系统缓存中没有,尝试从hosts文件中查找(C:\Windows\System32\drivers\etc\hosts)
  • hosts文件没有,递归去域名服务器查找
    (2)浏览器是怎么解析HTML的?
    前端--详解浏览器工作原理之HTTP请求其中,计算元素位置和尺寸的过程,如果元素的位置或尺寸发生变化,会发生重排和重绘。

HTTP缓存控制

Web缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN缓存)、浏览器缓存。其中,浏览器缓存又包含:HTTP缓存、indexDB、cookie、localstorage等等。
我们具体解释一下HTTP缓存:它的作用是提高服务器的并发性能,很多资源不需要重复请求,可以从浏览器中拿缓存。
浏览器第一次请求会发生如下过程:
前端--详解浏览器工作原理之HTTP请求“请求响应,缓存协商”会协商是否缓存右边红字内容。该缓存就是为之后的浏览器请求准备的。
浏览器第二次请求:
前端--详解浏览器工作原理之HTTP请求HTTP缓存主要有以下几个概念:

  • HTTP缓存作用范围
  • HTTP缓存分类
  • HTTP缓存实现技术

HTTP缓存作用范围,就是在第一次请求与第二次请求之间,也就是说,至少发起两次请求,才会有缓存范围这个概念。如上图所示,浏览器的第一次请求生成的缓存供第二次请求使用。

在了解缓存分类之前,我们先理解几个术语:

  • 缓存命中率:从缓存中得到数据的请求数与所有请求次数的比例,理想状态是越高越好
  • 过期内容:超过设置的有效时间,被标记为“陈旧”的内容,通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
  • 验证:验证缓存中的过期内容是否仍然有效,验证通过会刷新过期时间
  • 失效:把内容从缓存中移除。当内容发生改变时,必须移除失效内容。

HTTP缓存主要分为:强缓存协商缓存

强缓存:不用发请求到服务器就能拿到缓存文件的请求。
协商缓存:需要发请求到服务器,但是服务器并不会返回资源信息。
浏览器加载一个页面的流程如下:
(1)浏览器现根据这个资源的http头信息来判断是否命中强缓存,如果命中则直接加载缓存中的资源,不用向服务器发请求。(强缓存)
(2)如果未命中强缓存,浏览器会将资源加载请求发送到服务器,服务器来判断浏览器的本地缓存是否失效,如果没有失效,服务器就不会返回资源信息,浏览器继续冲缓存中加载资源。(协商缓存)
(3)如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。

前端--详解浏览器工作原理之HTTP请求状态码200,且Size显示memory cache的就是强缓存。
强缓存是利用http返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。
Expires
是一个绝对时间,用来指定资源的到期时间,是服务器端的具体的时间点,比如返回Thu,31 Dec 2021 10:34:30。在Expires返回的到期时间之前,缓存都是有效的。
Cache-Control
它是一个相对时间,比如Cache-Control:3000,意思是,资源的有效时间是3000秒。
那么,为什么需要两个字段表示缓存时间呢?原因是,Expires是一个绝对时间,如果客户端的本地时间被修改了,服务器与客户端的时间偏差变大,就会导致缓存混乱,由此才发展出了Cache-Control。
Cache-Control可以由多个字段组合而成,最主要的是max-age,它指定一个时间长度,在这个时间段内缓存是有效的,单位是秒。所以,Expires = max-age + 请求时间。

协商缓存是服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存,如果命中,则返回状态码304,浏览器从缓存中加载资源。
协商缓存协商的就是:浏览器问服务器我缓存的文件有没有更新嘞?
没有更新->浏览器可以用缓存 状态码304
更新了->服务器发新的资源给浏览器 状态码200

现在再来理解一下304状态码的定义:如果客户端发送了一个带条件的GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304状态码。简单的表达就是:服务端已经执行了GET,但文件未变化。

恍然大明白~~~~~

Last-Modify/If-Modify-Since

浏览器第一次请求一个资源的时候,服务器返回的响应头中会加上Last-Modify,Last-Modify是一个时间标识,指该资源的最后修改时间,例如Last-Modify:Thu,31 Dec 2021 10:34:30 GMT。当浏览器第二次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify,服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。(比较第二次请求头的If-Modify-Since与第二次响应头的Last-Modify是否相等,相等说明两次请求之间没有修改过)。
如果命中缓存,返回304,并且不会返回资源内容以及Last-Modify。

Etag/If-None-Match

ETag/If-None-Match返回的是一个校验码,ETag可以保证每一个资源都是唯一的,资源变化会引起ETag的变化,服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。判断方法与Last-Modify/If-Modify-Since类似,第一次请求,响应头返回Etag,第二次请求,请求头中携带If-None-Match,其值与Etag相同,如果If-None-Match与第二次请求的响应头中的ETag一致,则命中缓存。

那么,为什么已经有了Last-Modify/If-Modify-Since还要有ETag/If-None-Match呢?原因是Last-Modify/If-Modify-Since的时间精确到了秒,如果在一秒钟之内修改了,Last-Modify与If-Modify-Since的值仍然相等,判断不出来修改。另外,也存在服务器与浏览器时间不一致的问题。

ETag扩展:
ETag标签如何生成?以Apache为例,其生成因子由如下几个:
(1)文件的i-node编号,它是Linux用来识别文件的编号(ls -l可以查看)
(2)文件的最后修改时间
(3)文件大小
ETag的生成可以使用其中的一个或多个因子,使用抗碰撞散列函数生成。ETag有很小很小的重复概率,可忽略不计。

上一篇:CF1234E Special Permutations(思维+差分)


下一篇:Atlantis HDU - 1542