首先我们知道TCP的连接,它包含了三个过程,建立连接、传输数据、断开连接

HTTP协议,它正是建立在TCP连接基础上的。HTTP是一种允许浏览器向服务器获取资源的协议,是Web的基础。

了解一下之后,我们来带着下面的这些疑问,一步一步的走进HTTP吧:

  1. 为什么有些网站, 第一次打开慢, 第二次快一些???
  2. 当登录过一个网站之后, 下次再访问, 自动就是登录状态了???

浏览器发起HTTP请求流程


当我们在网站输入一个网址的时候, 比如http://www.baidu.com/index.html(只是打个比方), 浏览器会完成哪些动作?

1. 构建请求

首先,浏览器构建请求行信息(如下所示), 构建好后,浏览器准备发起网络请求。

GET /index.html HTTP1.1

2. 查找缓存

在发送请求之前, 浏览器会现在它缓存中查询是否有要请求的文件。当浏览器发现缓存中有存在的副本, 他就会拦截请求, 返回该资源的副本, 并直接结束请求, 而不会再去源服务器重新下载。

这样做的好处很明显吧:

  • 缓解服务器端压力, 提升性能(获取资源的耗时更短了);
  • 对于网站来说, 缓存是实现快速资源加载的重要组成部分。

3. 准备IP地址和端口

让我们先来看看HTTP和TCP的关系。HTTP协议是作为应用层协议, 用来封装请求的文本信息; 并使用TCP/IP作为传输层协议将它发送到网络上, 所以在HTTP开始工作之前,浏览器需要先通过TCP与服务器建立连接。这样就能理解, HTTP的内琼是通过TCP的传输数据阶段来实现的

我们来看下面这张图, 加深一下理解:
image.png

我们知道访问一个网站需要的是IP,当然还有端口, 但是当我们输入百度的网址时, 会发现URL上并没有IP, 咋回事呢??

这里来介绍一套能将输入的域名(www.baidu.com)映射为IP的系统, 这套系统叫做"域名系统", 简称DNS

当我们输入网址的时候, 其实他会先在本地查找是否有缓存这个域名的IP, 如果没有他就会去DNS服务器上查找对应的IP地址, 如果找到DNS服务器会返回你得IP地址并且缓存到浏览器中(DNS缓存), 当然缓存服务是浏览器提供的。那这样我们下次在输入相同域名的时候, 直接就可以从缓存中取出IP, 拼上端口进行请求了。

通常情况下, 如果URL没有特别知名端口号, 那么HTTP协议默认是80端口。

然后就会进行下一步

4. 等待TCP队列
不应该是三次握手么?不不不,还没到,Chrome有一个机制, 同一个域名同时最多只能建立6哥TCP连接, 如果在同一个域名下同时有10哥请求发生, 那么其中4个请求会进入排队等待状态, 直到进行中的请求完成。

如果,当前的请求数量少于6, 会直接进行下一步, 建立TCP连接。

5. 建立TCP连接
三次握手开始,如果不明白请看我上一篇文章

6. 发送HTTP请求
建立了TCP连接之后, 浏览器如何发送请求给服务器的???

我们看图来理解:
image.png

首先浏览器向服务器发送请求行, 它包括了请求方法、请求url和HTTP版本协议

请求行会告诉服务器,浏览器需要什么资源, 最常用的是GET请求。

但是我们有时候还需要用POST请求向服务器传递我们准备的数据, 这些数据就会在请求体中进行携带。

请求头会携带一些基础信息, 发送给服务器。比如Cookie、浏览器的操作系统、当前请求的域名信息等。

走过千山与万水, 我们就需要等待服务器处理HTTP请求, 然后返回给我们数据了。

服务器端处理HTTP请求流程

1. 返回请求

服务器处理结束之后, 就会返回数据给浏览器了。我来看下面这个图,理解他们之间的关系:
image.png

首先服务器会返回响应行,包括协议版本和状态码。

好像看到了熟悉的东西....状态码。没错,就是他,代表着返回的状态,例如200表示成功,404找不到页面...

随后, 服务器会向浏览器发送响应头。响应头包含了服务器的一些信息,比如:服务器生成返回时间、返回的数据类型(JSON、HTML、流媒体等类型), 以及客户端保存的Cookie信息等。

发送完响应头后, 服务器就可以继续发送响应体的数据,通常,响应体就包含了HTML的实际内容。

发送完了这些就可断开连接了。

2. 断开连接
正常情况下要进行TCP的四次挥手了,如果浏览器或者服务器想要在请求结束之后继续保持连接, 那就在信息头中加入:

Connection:Keep-Alive

这样会让TCP始终保持开启状态。保持开启状态可以省去下次需要建立连接的时间,提升资源加载速度。

3. 重定向
我们在浏览器中输入baidu.com, 你会发现最终打开的地址是https://www.baidu.com/, 这就是将你输入的网址重新定向到一个新的网址, 从而打开了一个正确的网站。

回到我们开始的问题:
1. 为什么很多网站第二次打开的时候会很快?

除了DNS缓存, 还有浏览器资源缓存, 大大提升了第二次打开页面的速度。

我们来看一下浏览器资源缓存的过程:
image.png

通过第一次请求, 我们可以看出当服务器返回HTTP响应头给浏览器的时候, 浏览器是通过响应头中的Cache-Control字段来设置是否缓存该资源

我们需要为缓存设置一个过期时长, 而这个时长是通过Cache-Control中的Max-age参数来设置的。

Cache-Control:Max-age:2000

其中的流程是这样的:

  • 浏览器发送请求给服务器之前, 会查看是否有缓存,是否过期, 有缓存没过期直接返回缓存中的资源, 给浏览器。
  • 如果过期, 准备IP端口, 建立TCP连接, 发送HTTP请求, 并且会在请求头中带上If-None-Match:"4f80f-13c-3a1xb12a"
  • 而服务器收到请求头之后,会根据If-None-Match的值来判断请求的资源是否更新过。如果没有返回304状态码, 告诉浏览器请继续使用缓存。如果更新了, 返回更新数据。

2. 登录状态是怎么保持的?

在用户登陆, 输入了用户名密码, 点击确认之后。发生了什么呢?我们来看一下下面这个图:

image.png

  • 首先, 浏览器会提交信息给服务器, 查询后台, 验证用户信息是否正确, 如果正确就会生成一个表名用户身份字符串, 并把该字符串写到响应头的Set-Cookie字段里Set-Cookie:UID=3431uad
  • 浏览器收到服务器的响应头之后, 开始解析, 如果遇到响应头中含有Set-Cookie字段,保存到浏览器本地。
  • 当用户再次访问的时候, 浏览器读取之前保存的Cookie数据, 并放在请求头里面Cookie: UID=3431uad, 然后发起HTTP请求。
  • 服务器接收到请求头数据之后, 查找携带的Cookie字段信息, 查询到之后判断用户已是登陆状态, 然后生成含有该用户信的的页面数据, 再返回给浏览器。
  • 浏览器在接受到含有用户的页面数据之后, 正确的展示用户登录状态的信息。

这就是登录时候, HTTP请求的过程。

总结:


本章节结合之前, 比较杂乱, 我们来用图总结一下包含之前的知识:
image.png

  1. 浏览器构建请求
  2. 浏览器查找有关本次请求的缓存
  3. 存在就用,不存在请求DNS,查找IP,准备端口
  4. TCP等待队列
  5. TCP三次握手建立连接
  6. 发起HTTP请求,发送请求报文。请求行、请求头、请求体。
  7. 服务器处理请求,解析请求报文。
  8. 服务器响应请求,发送响应报文。响应行、响应头、响应体。
  9. 断开TCP连接。

大V是个啥
10 声望1 粉丝

喜欢前端,不断学习的自我驱动型!!!