问:从浏览器里,从输入URL到页面展示,这中间发生了什么?
正文准备
(1)用户导航栏输入,输入内容决定去向
【处于浏览器进程】
搜索内容 | 那就将关键词与你设置的默认搜索引擎合成新的带搜索关键字的URL
请求URL | 如果符合URL规则,会添加上协议,合成完整URL
有了URL就可以进行下一步了。
URL的这一路
(2)浏览器进程将合成URL发送给网络进程
【处于浏览器进程->处于网络进程】
浏览器进程本身不做网络请求的事,这个需要交给浏览器内部的网络进程。
为何要发送给网络进程?
回顾浏览器进程相关知识:进程区分,各司其责,才做事有条不紊,高效有序
而在URL的这段旅途中,涉及到以下三个进程:
浏览器进程:负责用户交互、内存管理、文件储存等;
网络进程:为渲染进程和浏览器进程等提供网络下载功能;
渲染进程:将下载的资源进行解析,使其能够在页面显示和交互。
简单来说,浏览器进程管自家主机,网络进程用于外出提货,渲染进程用于货物加工处理。所以在URL请求这种外出活只能交给网络进程处理。
如何发送给网络进程
(3)网络进程拿到URL后会先在缓存中找,免得白请求一趟
【处于网络进程】
网络进程拿到资源URL后,并非立即动身,而是先看自己家(浏览器)缓存有没有,在设置了max-age的情况(其他情况看下方扩展一)下有三种情况:
1)缓存有资源!没过期!| 浏览器缓存有该缓存结果和缓存标识,同时缓存结果未失效
应对:既然有而且又没过期,那就直接拿来用,也免了请求的功夫,而这种情况就叫做强制缓存生效。
2)缓存有资源!过期了!| 浏览器缓存有该缓存结果和缓存标识,但缓存结果已失效
应对:这里虽然说过期了,但是我们知道其实有一些过期的还是可以再用的。所以就带着这个资源的缓存标识(具体包含什么看下方扩展二)跑去服务器问它是否还能用,能用继续用,不能用就取全新的回来用,这种情况就叫做强制缓存失效。
说到这,有人有疑惑了:反正都要发送请求去服务器,那为什么不直接取全新的回来用?
原因:如果资源很大,取回新资源将非常耗时,如果你所持有的旧资源还能用,那还费什么功夫去重新运输,你完全可以屁颠屁颠回去拿着接着用。
过期了还能用!| 资源没有更新,缓存结果仍能继续使用
应对:如果资源没有更新,原来的缓存仍能使用,将回去直接使用缓存中的结果。服务器通过返回304的标识告知你资源无更新、缓存可用。这种情况就叫做协商缓存生效。
过期了不能用了!| 资源有更新,需要取回新资源回去使用
应对:既然资源都有更新了,那旧的肯定不能再用了,那就从服务器取回最新资源使用,同时会把这次取回的新资源作为新的缓存存储在浏览器缓存中。服务器直接返回200标识和新的请求结果来间接告知你:旧的资源没用了,扔了吧,新的给你。这种情况就叫做协商缓存失效。
3)缓存没有资源!| 浏览器缓存压根没有该缓存结果和缓存标识
应对:对于根本没有相关缓存的情况,那自然而然是得前往请求了。
整个过程的流程图

(4)缓存中没有或需要经过协商缓存,那就开始真正向服务器发送请求了
【处于网络进程】
但是要真正发出请求,还需要做足准备。
首先便是需要获取到请求域名服务器的IP地址。而具体的获取过程那就需要DNS解析了。
DNS解析 | 将域名解析为IP地址

解析出IP地址后,我们知道发送http请求需要先建立TCP连接,这里还有区分请求协议是HTTPS还是HTTP,如果是HTTP,直接三次握手建立TCP连接;而HTTPS需要先建立TLS连接才能进而三次握手建立TCP连接。
TLS连接 | 通过非对称加密保证数据传输安全
SSL/TLS是不同时期的同一技术的命名,所以其实是同一样东西
对称加密 VS 不对称加密
对称加密,双方使用同一个密钥加密数据和解密数据。
不对称加密,加密和解密是使用不同的密钥,加密只能通过公钥加密,解密只能通过私钥解密,但能实现私钥解密后的消息与公钥加密前的消息一致。HTTPS中,服务端存有公钥和私钥,用于加密的公钥可以对外公布,但是要解密只能通过自己手上的私钥。
对称加密导致HTTP有三大明显缺点:
- 明文传输,易被窃听
- 不验证通信方身份,易遭遇伪装
- 无法证明报文完整性,易糟篡改
TSL连接过程

在经过三次握手TCP连接建立后。浏览器端会构建请求行、请求头等信息,并且自动将和该域名相关的Cookie等数据附加到请求头中,然后真正向服务器发送请求信息。
(5)拿到服务器的响应后开始解析
【处于网络进程】
而这里又有三种解析情况:
资源地永久搬家了 | 响应返回301状态码和Location重定向地址,永久重定向
应对:这种情况下会认为原URL中的资源地已经永久搬到新的位置Location,以后再进行该url请求时浏览器会自动使用Location中的URL,而非原有的URL。在这种情况下,是没有请求到资源的,所以得知搬家后还会重新向新的资源地发起请求取数据。
资源地址临时搬家了 | 响应返回302状态码和Location重定向地址,临时重定向
应对:这种情况下会认为原URL中的资源地临时搬到新的位置Location,不同永久重定向,这种情况以后再进行url请求时仍会向原有的URL发起。在这种情况下,同样是没有请求到资源的,所以得知搬家后还会重新向新的资源地发起请求取数据。
资源地址返回有效资源了 | 响应返回200状态码,返回资源
应对:这种情况当然是最喜闻乐见的,即是资源地没有搬家,成功返回需要的资源。
(6)真正的资源拿到手了,浏览器看着Content-Type来处理
客户端拿到服务端响应数据后,浏览器可不是随便拿来用的,它要根据Content-Type这一字段的值来判断请求回来的数据该怎么用。
Content-Type
| 类型值 | 说明 | |
|---|---|---|
| text/(html、plain、xml) | 分别是HTML格式、纯文本格式和XML格式,三选一 | |
| image/(gif、jpeg、png) | 分别是gif图片格式、jpg图片格式和png图片格式,三选一 | |
| 下方为常见的application开头的每题格式类型 | ||
| application/json | JSON数据格式 | |
| application/pdf | PDF格式 | |
| application/msword | WORD文档格式 | |
| application/octet-stream | 二进制流数据,常见的文件下载 | |
| application/x-www-form-urlencoded | form表单中默认的encType值,将表单中数据转换为key/value的形式进行传输(不会拿来传文件,因为它不适合用于传输大型二进制数据或者包含非ASCII字符的数据) | |
| multipart/form-data | 专门用于有效的传输文件 |
不同的值会让浏览器有不同的处理方式,所以如果Content-type没有设置成正确的值,将得不到想要的显示结果。例如:一个期望作为HTML文件显示的资源,没有设置成text/html反而设置成application/octet-stream,这会让浏览器认为这是一次文件下载,浏览器会将请求交给浏览器内的下载管理器,这也导致不会有任何内容显示在屏幕页面中。
接下来我们假如拿到的页面文件的确是text/html数据格式,这样浏览器将会把数据交给内部的渲染进程处理。
(7)浏览器给HTML页面准备渲染进程
通常打开一个新的页面都需要采用单独的渲染进程,但是有个例外:
A页面中打开B页面,如果A与B属于同一站点,那B将复用A页面的渲染进程。
同一站点?
当页面的根域名与协议相同时,则为同一站点。
https://time.geekbang.orghttps://www.geekbang.orghttps://www.geekbang.org:8080
以上便是属于同一站点,根域名“geekbang.org”和协议“https”是相同的,所以为同一站点。
(8)浏览器向渲染进程“提交文档”
这里的文档指的是URL请求的响应体数据。提交过程四步走:
- 浏览器向渲染进程发出“提交文档”的消息
- 渲染进程接收到消息后和网络进程建立传输数据的“管道”
- 数据传输完成后,渲染进程返回“确认提交”的消息给浏览器进程
- 浏览器收到消息后,更新界面状态(安全状态、地址栏URL、前进后退历史状态以及Web页面)
(9)渲染进程开始渲染
具体渲染过程下一篇文章再总结。
渲染完成后,渲染进程会发送消息给浏览器进程,浏览器进程接收到后停止页面标签的加载动画,也即意味页面加载完成。
总结并回答第一行的问题
答:① URL输入后,浏览器先根据输入内容进行判断,如果符合URL规则,将合成完整URL进行请求,否则会当成搜索内容与默认搜索引擎合成带搜索关键词的URL进行请求;② 合成URL后,浏览器进程会将其通过IPC通信技术发送给浏览器中的网络进程;③ 网络进程会先查找是否有相关缓存,有且未失效,强制缓存生效,不再发送网络请求;如果缓存失效了,会经过协商缓存决定是否使用缓存;④ 如果没有相关缓存,网络进程开始真正发送请求,在建立TCP连接前,会通过DNS域名解析服务器IP地址,随后如果是https协议需要先建立TLS连接,最后建立TCP连接;⑤ 建立连接后发送请求且拿到服务器的响应数据后,会开始解析响应头字段,如果是301或302,则是需要重定向地址,浏览器会重新发送请求到重定向的地址;⑥ 取回数据后如果是HTML页面,浏览器将为其分配渲染进程,并进入提交文档阶段;⑦ 待渲染进程完全取得网络进程请求回来的资源数据后,会返回“确认提交”消息给浏览器进程,浏览器开始更新界面状态;⑧ 渲染进程开始真正渲染HTML页面;⑨ 渲染完成后,渲染进程发送消息给浏览器进程,浏览器接收后停止页面标签的加载动画。
这就是URL输入到页面展示的全过程。
相关扩展
一、是否缓存,怎么缓存,这个看Cache-Control
| 能够设置的值 | 作用 | |
|---|---|---|
| public | 所有内容都将被缓存(客户端和代理服务器都可以缓存) | |
| private | 只有客户端可以缓存,默认取值 | |
| no-cache | 客户端可以缓存内容,但每次用缓存前都需要经过协商缓存来验证决定 | |
| no-store | 完全不可以缓存,不存在强制缓存和协商缓存 | |
| max-age=xxx (时间,单位秒), must-revalidate |
缓存内容在xxx秒内是有效的,过期后必须要经过协商缓存 |
Expires头字段也可以控制网页缓存,但是它使用绝对时间控制,相对Cache-Control的相对时间,存在客户端与服务端时区误差的缺点,所以Cache-Control优先于Expires。但是,它也有自己作用,如果服务器上的网页经常变化,就把它设置为-1,表示立即过期。
二、协商缓存中的重要缓存标识
| 重要字段 | 作用 | |
|---|---|---|
| Last-Modified | 服务器响应时,在返回结果加上的字段,用于表示该资源文件在服务器最后被修改的时间 | |
| Last-Modified-Since | 客户端在发现缓存结果过期时,通过该值保存缓存结果中的“Last-Modified”值,发送请求到服务器后,服务器会判断是否缓存结果已过期,实则返回200和新的结果,否则返回304。 | |
| Etag | 服务器响应时,在返回结果加上的字段,是资源文件的一个唯一标识,又服务器生成。 | |
| If-None-Match | 客户端在发现缓存结果过期时,通过该值保存缓存结果中的“Etag”值,发送请求到服务器后,服务器会判断该值是否和服务器中的Etag一致,不一致则认为资源有更新,返回200和新的结果,否则返回304。 |
Etag/If-None-Match 优先于 Last-Modified/Last-Modified-Since
End
参考如下
1.彻底理解浏览器的缓存机制
2.Cache-control使用Cache-control:private学习笔记
3.一篇文章看明白 HTTP,HTTPS,SSL/TSL 之间的关系
