HTTP请求过程解析

1 篇文章 0 订阅
1 篇文章 0 订阅

什么是HTTP请求过程?
这是一个直到现在也隐隐约约威胁着小白鼠的问题,发送get,post请求,服务端就直接解析了吗?

No!

在你真正去了解和挖掘之后,你会发现,在这个过程中,请求发生了很多不可思议的故事

Start:

HTTP请求过程大致分为以下四步:

  1. 读取浏览器缓存
  2. CDN解析域名获取IP地址
  3. TCP协议(握手,传输,挥手)
  4. HTTP发送请求和响应

为什么浏览器缓存放在第一位?

因为浏览器中如果存在缓存数据,并且没有过期,那么浏览器会优先读取缓存数据而不会去发送请求,但如果没有缓存,我们继续往下看

浏览器缓存机制

如果想知道如何读取浏览器缓存,我们必须要知道浏览器缓存的机制

  1. 强制缓存(本地缓存) Expires/Cache-control
  2. 协商缓存 Last-Modifed/Etag

由于浏览器和服务器的通信基于TCP,属于应答的请求方式,所以在客户端第一次向服务端发送请求并得到结果时,会根据响应报文中的HTTP头的缓存标识来绝对是否进行缓存

在这里插入图片描述

  1. 每次发起请求,都会现在浏览器缓存中查询该请求结果和缓存标识
  2. 浏览器每次拿到返回结果都会将该结果和缓存标识存入浏览器缓存

强制缓存(本地缓存)

强制缓存就是向浏览器缓存查找缓存结果和缓存标识,并根据返回结果的缓存表示和规则来决定是否使用该缓存结果

  1. 如果该请求结果和缓存标识不存在,则强制缓存失败,需要再向服务器解析域名获取IP地址

在这里插入图片描述

  1. 如果该请求结果和缓存表示存在,但该请求结果过期,则强制缓存失败,需要使用协商缓存

在这里插入图片描述

  1. 如果该请求结果和缓存表示存在,但该请求结果未过期,则直接返回缓存结果

在这里插入图片描述

强制缓存的规则
浏览器向服务器发送请求时,服务器会将缓存规则存放在HTTP相应报文的请求头中和请求结果一起响应给浏览器。
控制强制缓存的字段分别是Expires和Cache-Chntrol,其中Cache-Control比Expire优先级高,但在新的HTTP协议中,Expire已经被Cache-Control取代

Cache-Control控制网页缓存的等级划分:

  • public:所有内容都被缓存
  • private:只有客户端可以缓存,Cache-Control的默认值
  • no-cache:客户端缓存内容,决定权在协商缓存
  • no-store:所有内容都不会被缓存
  • max-age = xxx (xxx is numberic):缓存内容将在xxx秒后失效

协商缓存
在强制缓存失效后,浏览器携带缓存标识向服务器发送请求,由服务器根据缓存标识决定是否继续使用缓存

  1. 协商缓存生效,返回304

在这里插入图片描述

  1. 协商缓存失效,返回200和请求结果

在这里插入图片描述

导致缓存失效的原因

协商缓存的控制字段有 Last-Modified /If-Modified-Since 和 Etag/If-None-Match。 Etag/If-None-Match的优先级比Last-Modified /If-Modified-Since 高

Last-Modified
表示一个服务器上的资源的最后修改时间,资源可以是静态的或者动态的内容。一般在第一次请求时服务器发给客户端的缓存标识

If-Modified-Since
客户端再次发送该请求时,携带上次请求返回的Last-Modified值,服务器收到该请求,发现 If-Modified-Since字段,如果服务器资源的最后修改时间大于If-Modified-Since的值,则重新返回新资源,状态码为200,此时则表明协商缓存失效,之前的缓存不再使用。否则,返回304,资源没有被更新,协商缓存生效,继续使用浏览器缓存。

Etag
Etag是服务器响应请求时,返回当前资源文件的唯一的编号

If-None-Match
客户端再次发起该请求时,携带上次请求返回的唯一编号,服务器收到请求后,将If-None-Match的字段值与该资源在服务器上的Etag值做对比,一致则返回304,说明资源无更新,协商缓存生效,继续使用缓存文件,不一致说明资源已更新,重新返回资源文件,状态码为200

现在我们已经了解了浏览器缓存的机制,那么浏览器的缓存到底是什么呢?

浏览器缓存分为两种,内存缓存磁盘缓存
内存缓存(from memory cache):具有两个特点,分别是快速读取和时效性:

  1. 快速读取: 内存缓存会将编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内部资源,以方便下次运行使用时的快速读取
  2. 时效性:一旦进程关闭,则该进程的内存则会清空。

硬盘缓存(from disk cache): 硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。

用户的操作和缓存的关系表

用户操作Expires/Cache-ControlLast-Modifed/Etag
地址栏回车truetrue
页面连接跳转truetrue
新开窗口truetrue
前进后退truetrue
F5刷新falsetrue
Ctrl+F5强制刷新falsefalse

浏览器缓存总结图

在这里插入图片描述
注意:第一次访问一个请求时,此时浏览器不存在缓存,需要去服务器中获取,去服务器中获取就需要解析域名获取IP,这就设计到了第二个步骤DNS域名解析

DNS域名解析

互联网都是通过URL地址来发布请求资源的,而URL需要DNS解析成IP才能够与远程主机建立连接

什么是DNS?
它是一种组织成域层次结构的计算机和网络服务命名空间系统,应用于TCP/IP网络,它提供的服务是将主机名和域名转换为IP地址的工作

分层式DNS域名服务器的划分

  • 根域名服务器

最高层次的域名服务器,也是最重要的域名服务器,所有的根域名服务器都知道所有的顶级域名服务器的域名和IP地址

  • 顶级域名服务器(TLD服务器)

管理在该顶级域名服务器注册的二级域名

  • 权威域名服务器

如阿里和腾讯云,华为云自己申请搭建的域名,.net .tech等

还有一个本地域名服务器,它对域名系统非常重要,当一台主机发出DNS请求时,这个请求报文首先发送给本地域名服务器

DNS域名解析过程

  1. 检查浏览器缓存中是否存在该域名对应解析过的IP地址

如果缓存中存在该域名解析过得IP地址,则解析结束,发送请求,否则继续向下解析。
需要注意的是:浏览器缓存有大小和时间限制

  1. 如果浏览器缓存中没有

用户的浏览器缓存中不存在这个域名对应的解析结果,则浏览器会查找操作系统缓存中是否有这个域名对应的DNS解析结果,windows和linux都在host文件中可以查

  1. 向本地服务器查看(LDNS)

如果前两个过程都无法完成解析,则操作系统会把这个域名发送给LDNS,也就是本地的域名服务器
LDNS 即用户本地DNS, CDN 调度系统会通过这个ip来给用户分配CDN 节点

  1. LDNS没有命中,直接到Root Server域名服务器请求解析

Root Server就是最高等级的根域名服务器,所有的根域名服务器都知道所有的顶级域名服务器的域名和IP地址

  1. 根域名服务器返回给本地域名服务器一个所查询与的主域名服务器(gTLD Server)地址

gTLD就是国际顶级域名服务器,com cn等等

  1. 接受请求的顶级域名服务器查询并返回此域名对应的权威服务器

权威服务器就是注册的域名服务器,比如阿里,华为,腾讯的域名服务器

  1. 权威服务器查询存储的域名和IP的映射关系表并返回

在得到目标IP后,联通TTL值一起返回给DNS Server域名服务器

  1. 将解析的IP地址返回给用户,用户根据TTL值缓存在本地系统缓存中,域名解析就结束了

DNS域名解析过程中的查找方式

  • 递归查询

主机向域名服务器的查询大多都采用递归查询,什么是递归查询?
如果主机访问的本地域名服务器不知道被查询域名的IP地址,那么本地域名就求的顶级域名服务器查询并会以DNS客户的身份代替主机向其他根域名服务器继续发出查询请求报文,而不是主机本身

  • 迭代查询

本地域名服务器向根域名服务器的查询通常是采用迭代查询,什么是迭代查询?
根据明服务器收到本地域名服务器发送的迭代查询请求报文时,要么给出IP地址,要么告诉本地域名服务器下一步应当向哪一个域名服务器查询,然后让本地域名服务器进行后续的查询操作

DNS中的缓存
DNS域名解析后会缓存解析结果,其中主要在两个地方缓存结果,本地域名服务器和用户的本地及其,这两个缓存都是由TTL值和本机缓存大小控制

DNS图解
在这里插入图片描述

2019.9.4
因为昨天产品发版上线,我待执行刷库脚本,所以没有写完,今天接着写。

了解了浏览器缓存,也了解了DNS解析,那么接下来,就是了解如何建立IP与服务器之间的连接关系,只有这个连接关系存在的时候,才能够与服务器进行通信

首先,什么是TCP连接?

在浏览器发送HTTP请求到服务器之间,需要建立一条TCP/IP的连接,每一条的TCP连接都被通信两端的端点确定,这种连接的端点也叫作套接字。根据FC 793的定义,端口号拼接 到IP地址就构成了套接字。而一次TCP连接主要分为建立连接,数据传输,断开连接

TCP连接三步骤:

  1. 建立连接三次握手
  2. 传输数据
  3. 断开连接四次挥手

在这里插入图片描述
TCP报文段首部的概念:
在这里插入图片描述
在了解TCP的三次握手和四次挥手之前,我们务必先了解和TCP连接有关的报文段首部的几个控制位和初始序列号

  • 确认号

确认号是期望收到对方下一个报文段的第一个数据字节的序号,假如B正确收到A发送过来的一个报文段,其序列号字段值为501,而数据长度是200字节(序列号501~700),这表明B正确收到了A发送的序列号为700为止的数据。所以B期望收到A的下一个数据序列号为701,于是B将确认是置为701,表示ACK = 701。所以,如果确认号=n,则n-1之前的所有数据都已正确收到

  • 确认ACK

ACK标志位用于确认收到

  • 同步SYN

用来初始化一个连接的同步序列号,当建立一个新连接时,从客户端发送到服务器的第一个报文段的SYN位字段将被启用

  • 终止FIN

用户释放连接(也就是断开连接),当FIN = 1时,表明此报名文的发送方数据已经发送完毕,并要求释放/断开运输链接

  • 序列号

由于TCP是面向字节流的,在一个TCP连接传输的字节流的每一个字节都按照顺序编号,整个传输要传输的字节流的起始序列号必须在连接建立的时候设置,那么,这里的序列号就是TCP三次握手过程中的初始序列号。在<TCP/IP详解 卷1:协议>中提到,在一个连接中,TCP报文段在经过网络路后可能会存在延迟抵达与排序混乱的情况,所以为了解决这个问题,需要仔细选择初始序列号,所以现代系统通常采用半随机的方法选择初始序列号,保障一定的安全性

注意: 确认号是针对接收方而言的,接收方希望收到发送方下一个报文段的第一个数据字节的序列号,而SYN所初始化的序列号是针对发送方,在建立连接阶段,发送方和接收方都要发送自己的初始序列号。

在这里插入图片描述

TCP三次握手:

  • 第一次握手(进入同步已发送状态)

客户端在建立TCP连接时,向服务器发送连接请求报文段(也就是SYN报文段)设置首部微中的同部位SYN = 1,同时随机选择一个初始序列号 seq = x 。TCP规定,SYN报文段(SYN = 1)不能携带数据,但要消耗掉一个序列号,这是TCP客户进程进入SYN - SENT(同步已发送)状态

  • 第二次握手(进入同步收到状态)

服务器收到连接请求报文后,即统一建立连接,则向客户端发送确认,在确认报文段(SYN + ACK段)中把SYN位和ACK为都设置为1,确认号 ack = X + 1,标识服务器希望从客户端这边接收到数据的序列号。同时也为自己随机选择一个初始序列号 seq = y。
**注意:**这个报文段也不能袖带数据,但同样要消耗一个序列号,这是TCP服务器进程进行SYN(同步收到)状态

  • 第三次握手(已建议连接状态)

客户端收到服务端发送的确认ACK后,还要再次向服务器给出确认,确认报文段的ACK设置为1,确认号ack = y + 1,而自己的序列号 seq = x + 1,TCP的标准规定,ACK报文段可以携带数据,但如果不懈怠数据则不消失序列号,在这种情况下,下一个数据报文段的序列号仍然是seq = x + 1。这时,TCP连接已经建立,客户端进入已建立连接状态,服务端收到确认后,同样也会进入已连接状态

TCP为什么是三次呢?
A:喂
B:啊,你说
A:bibibiiibibibib

两次
A:喂
B:bibibibibibibibib

一次
A:喂…

**注意:**三次握手的目的不仅在于通信双方了解一个连接正在建立,还在于利用数据包的选项来称在特殊的信息,确保通信双方是可靠的

TCP四次挥手:
在这里插入图片描述

  • 第一次挥手(终止等待状态)

客户端向服务器发出连接释放的报文段(就是FIN标志为1的报文段),并停止再发送数据,客户端把连接释放的报文段首部的终止控制位FIN设置为1,其序列号 seq = u,它等于前面已传送过的数据的最后一个字节的序列号+1,这时客户端进入FIN-WAIT-1(终止等待1)状态

  • 第二次挥手(终止等待状态2)

服务区收到连接释放报文段后立即发出确认,确认号 ack = u + 1,而这个报文段自己的序列号是v,等于服务器前面已传送过的数据的最后一个字节的序列号+1,然后服务器进入关闭等待状态。此时的TCP连接处于半关闭状态,即客户端已经没有数据要发送了,但服务器可能还有数据要发送,客户端是仍然要接受的。
**注意:**服务器到客户端这个方向的连接并没有关闭,并会持续一段时间。客户端收到来自服务器的确认后,就进入终止等待2的状态,等待服务器发出释放连接报文段

  • 第三次挥手(最后确认)

如果服务器已经没有向客户端发送数据,其应用的进程就通知服务器释放连接。此时服务器发出的释放连接报文段必须是FIN=1,并进入最后确认状态

  • 第四次挥手(时间等待)

客户端收到服务器的连接释放报文段后,立即对此发出确认。在确认报文段中把ACK设置为1,确认号ack = w + 1。而自己的序列号是 seq = u + 1,然后进入时间等待状态,此时,TCP连接还没有释放,需要等待时间计数器设置的时间2MSL过后,客户端才会进入关闭状态
什么是2MSL? https://blog.csdn.net/zxx2096/article/details/80286577

TCP的半关闭

TCP的半关闭就是当一方已经完成了数据的发送工作,并发送给了一个FIN给对方,但是它仍然希望接受来自对方的数据,直到对方发送一个FIN给它,这种情况下,它就处于TCP的半关闭状态

为什么客户端要在TIME-WAIT状态必须等待2MSL的状态?

TIME_WAIT状态也成为2MSL等待状态,在这种状态下,TCP将会等待两倍于最大生存周期MSL的时间,也成为加倍等待,这样就能够让TCP重新发送最终的ACK以避免出现丢失的情况,重新发送最终的ACK并不是因为TCP重新传递了ACK,而是因为通信的另一方重新传递了它的FIN序列号

小总结:
客户端先向服务器发送关闭请求,表示客户端不再发送请求数据了,服务器确认,但是此时客户端和服务器处于"半关闭"状态,服务器还可以接着向客户端发送消息,待服务器没有数据传输时,服务器再向客户端发送关闭请求,然后客户端确认,关闭连接

HTTP请求和响应

浏览器与服务器建立TCP连接后,就可以发起HTTP请求了,客户端按照指定的格式开始向服务器发送HTTP请求,服务器接受请求后,解析HTTP请求,返回HTTP响应给客户端

在这里插入图片描述

HTTP的请求报文和响应报文

HTTP的请求报文与响应报文结构一样,都是分为报文头部和报文主体部分,请求报文中的主体部分是主要发送给服务器的数据(比如post,put,delete请求),而响应报文总的主体也是返回给客户端的响应数据

在这里插入图片描述

请求报文和响应报文的首部内容组成:

  • 请求行:包含用于请求的方法,URL,HTTP等
  • 状态行:包含表明响应结果的状态码,原因短句和HTTP版本
  • 首部字段:包含表示请求和响应的各种条件和属性的各类首部
  • 其他:包含HTTP的RFC里未定义的首部(Cookie)等

在这里插入图片描述

现在相信大家已经了解的差不多了吧,综上所述,浏览器的URL请求过程就是
浏览器缓存=》DNS域名解析=》TCP连接=》HTTP请求

原文链接

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值