输入baidu.com,简单敲下回车的背后最近面试,总有不同的公司问我有关http的问题,虽然说或多或少都能答上来一些,
前言
最近面试,总有不同的公司问我有关http的问题,虽然说或多或少都能答上来一些,但看着面试官淡漠的眼神就知道这题完蛋🥲。所以这两天也搜罗了一些文章或是视频来补充自己对这方面的理解。在这写成一篇笔记吧,以便记忆以及总结巩固。
一、DNS解析
当我们在搜索框手动输入 www.baidu.com 时,浏览器到底是做了什么呢? 首先就是 DNS解析。
DNS 解析是一个分布式数据库系统,为了将域名,例如baidu.com,转换为对应的IP地址。
前面的www就是一个约定俗成的习惯,用于指代网站的主服务器,通常被用作一个域名的一部分,这里不需要过多关注。
那么为什么需要域名呢?其实完全只是为了好记罢了,毕竟作为一个这么有排面的公司,无论是从知名度还是简便性考虑,这都比一串ip地址要很得多。
DNS解析的过程是这样的。
- 到本地域名服务器,一般是互联网服务提供商提供的,查找域名对应的ip
- 找不到,就到根域名服务器查找域名对应的ip
- 再找不到,就到顶级域名服务器查找域名对应的ip
- 还找不到,就到目标域名服务器查找域名对应的ip
- 找到后,将ip写入DNS缓存,方便下次直接在本地查找的到这个域名对应的ip
这样才是和我们直接输入ip地址是一样的。只要将上面的图示理解清楚,那对应的DNS解析的题也就手到擒来。
二、建立连接
客户端需要和服务端先建立连接,就要提到 TCP协议了。三次握手,大家应该都很清楚了,这也是我第一次被问到的这类问题,我回忆起来,答的应该还行。
1. 三次握手
- 客户端向服务端发送建立连接请求,客户端进入SYN-SENT状态
- 服务端向客户端发送同意连接的应答,服务端进入SYN-RECEIVED状态
- 客户端接收到服务端的同意应答后,再向服务端发送一个确认收到的应答,客户端进入ESTABLISHED状态,服务端也进入ESTABLISHED状态
为什么一定要三次握手,两次行不行?
有一种情况,客户端向服务端发送第一个连接请求A,但是A因为某种非人为原因到达不了服务端,此时因为TCP协议内定的超时重传机制,客户端将会再一次发送请求,这里称为B。后面一切正常,客户端也接收到了服务端发来的数据,然后自然而然的关闭连接。这时候丢失的连接请求A又到达了服务端,服务端也就处于连接状态,等待客户端的数据请求,但是此时客户端并不知道之前发送的连接请求到达了服务端,所以始终处于关闭连接状态,这样服务端就会一直处于等待状态,浪费性能。
所以第一次的握手就是让服务端明白自己拥有接收请求的能力,然后服务端发送第二次握手,如果客户端成功接收到后,就明白自己能够发送请求,毕竟自己都接收到了对方的答复,也代表能接收请求。但是这样服务端并不知道自己的第二次握手对方有没有接收到,所以客户端需要发送第三次握手,等到服务端成功接收到后,就代表双方都拥有发送和接收请求的能力。
2. 数据传输
做完连接,就可以开始正式的 HTTP数据传输了。其实要说的话,建立连接的时候也就可以传输数据了,只是很小而已。
数据传输用到的是 HTTP协议,TCP协议是专门用来建立连接用的。下面就介绍一下HTTP的历史版本,里面也有一些常考的题。
HTTP 0.9
HTTP协议是超文本传输协议,一开始被打造是用来实验室传输html文本。
请求行采用 GET 方法,后跟一个空格,接着是资源的路径。GET /index.html
传输的 HTML 文件是以 ASCII 编码的纯文本文件,不支持二进制数据传输。
HTTP 1.0
0.9 的问题:多种类型的资源文件需要被传输。
所以增加 请求头、响应头 -- 实现客户端和服务端的交流。
请求头:
- accept: text/html 表示客户端可以接受 HTML 格式的文档。
- accept-encoding: gzip,deflate,br 表示客户端支持的数据压缩格式。
- accept-Charset: utf-8 表示客户端优先接受 UTF-8 字符集的数据。
- accept-language: zh-CN,zh;q=0.9,en;q=0.8,pt;q=0.7 表示客户端首选的语言和地区。
响应头:
- content-encoding: br
- content-type: text/html;charset=utf
HTTP 状态码用于表示服务器响应的状态。常见的状态码有这些:
2xx 成功:
- 200 OK:请求已成功,响应中包含所请求的信息。
- 201 Created:请求已成功创建资源。
- 204 No Content:服务器已经成功处理了请求,但没有返回任何内容。
3xx 重定向:
- 301 Moved Permanently:请求的资源已被永久移动到新位置。
- 302 Found:请求的资源临时位于另一个 URI。
- 304 Not Modified:客户端请求的资源尚未更改,使用缓存版本即可。
4xx 客户端错误:
- 400 Bad Request:请求语法错误。
- 401 Unauthorized:请求要求用户的身份认证。
- 403 Forbidden:服务器理解请求客户端的请求,但是拒绝执行此请求。
- 404 Not Found:请求的资源不存在。
5xx 服务器错误:
- 500 Internal Server Error:服务器遇到未知的错误。
- 502 Bad Gateway:作为网关或代理工作的服务器,从上游服务器收到了无效响应。
- 503 Service Unavailable:服务器目前无法使用(由于超载或停机维护)。
这样的一些状态码只有多记了,一般的话一些常见的报错看多了也就自然而然的记住了。
HTTP 1.1
1.0 的问题:HTTP的短连接。
1.1 建立了长连接,也叫持久连接。 在1.0版本中,每次客户端向服务端请求数据都需要经历三次挥手、发送请求、接收响应、四次挥手这几个步骤,也不是说这些步骤不重要,只是当浏览器先请求html,接着又需要css,这样一次次的建立连接,断开连接是很浪费时间的。
虽然允许同时建立最多六个TCP连接,每个连接又可以有多个 http请求,但是并不能同时发送请求,而是需要等待上一次的请求和响应都到位后,接着才可以发送下一次的请求。这也被称为 http队头阻塞,也几乎是这方面必考的题。
在1.0的版本中还允许对虚拟机的支持。每台物理设备都有对应的ip,但是虚拟机呢?是也有对应的ip吗? 看个例子吧。
假设有一台物理服务器,IP 地址为 192.168.1.100
,并设置了桥接模式的虚拟机网络配置:
虚拟机 A:
- IP 地址:
192.168.1.100
- 域名:
example.com
虚拟机 B:
- IP 地址:
192.168.1.100
- 域名:
anotherexample.com
访问过程
1.用户访问:
- 用户在浏览器中输入
example.com
。 - 浏览器向 DNS 服务器发送请求,解析
example.com
的 IP 地址。 - DNS 服务器返回
192.168.1.100
。
2.HTTP 请求:
- 浏览器向
192.168.1.100
发送 HTTP 请求。 - HTTP 请求中的
Host
字段包含example.com
。
3.服务器处理:
- 物理服务器接收到请求后,根据
Host
字段中的域名example.com
将请求路由到虚拟机 A。
正是为了处理虚拟机这种复杂的 ip地址关系,请求头中增加了新的字段 HOST。再提一句,cookie 也是在这个版本中新加的。
HTTP 2.0
1.1 的问题:带宽的利用率低。
- TCP的慢启动:TCP 的慢启动是一种用于控制网络拥塞的算法。在 TCP 连接建立初期,发送方会逐渐增加发送数据的速率,直到达到某个阈值,然后进入拥塞避免阶段。
- 同时开启的多条TCP连接相互竞争带宽
- http队头阻塞
所以出现 --- 多路复用 --- 解决1.1的后面两个问题
- 打造了一个二进制分帧层,将多个请求利用二进制分帧层处理成一帧一帧的请求,每一帧带上相应的id编号,服务器接收到所有的帧后,会根据相同的ID合并一个完整的请求。服务器响应该请求,将响应头和响应体发送给二进制分帧层,浏览器接收到响应帧后,自行合并成完整响应体。
- 多路复用当中可以给重要的资源添加标记,服务器会优先响应权重高的资源
- 通知只能最多开启一条TCP连接
在这个版本中,引入了许多新特性来提高网络性能,其中包括头部压缩。用于减少请求和响应头部的大小,从而提高网络传输效率。 使用 HPACK 算法来压缩请求和响应头部,它结合了静态压缩表和动态压缩表来实现高效压缩。压缩后可以减少带宽使用、加快响应时间、减少往返次数。
HTTPS VS HTTP
HTTPS和 HTTP的差别,应该都可以说出来 HTTPS 是加密用的,但是具体是怎么回事呢,在这里看看吧。
TLS协议
- 对称加密:客户端和服务端都有一个相同的密钥,公用相同的一把锁,这样就只有你们才只能打开这把锁,但是你得先要让服务端拥有相同的密钥,这还是需要发送请求,在这个过程也有可能被别人窃取到。
- 非对称加密:为了使客户端和服务端都能拥有相同的密钥,就出现了公钥,公钥是另一把锁,每个人都知道怎么锁上这把锁,所以客户端将你的锁和密钥都使用这把锁锁起来,发送给服务端,这样即使被窃取别人也无法打开这把锁,只有服务端能够使用私钥开打公钥,得到客户端发送的密钥。
HTTP + TLS = HTTPS
HTTP 3.0
介绍这个最新版本前,先来说一下 UDP 协议。
UDP 和 TCP 的区别:
TCP:
- 可靠性:建立连接;流量拥塞控制;超时重传机制(假如你有一个TCP快递,买了床的框架、床头柜和床垫,如果床头柜丢失了,那么快递会暂停,直到给你补发的床头柜到了,再接着发剩下的床垫)
- 有序性(没有床头柜也不影响我的床啊,但是TCP始终贯彻保证到手内容不丢失,不打乱发送顺序)
UDP:
- 不可靠:无连接;流量拥塞控制;不管丢包
- 高效
- 注重实时性,比如打视频、打游戏、直播,卡了不要求回退回去
2.0 的问题:
- TCP的队头阻塞:主要因为超时重传,在传输数据包的过程中,一旦出现某一个包丢失,后续的所有数据包都要等待该丢失的数据包重新整理打包发送,后续包才能继续传输。
- TCP建立连接的延时
QUIC协议
QUIC协议 = TCP + UDP
- 实现了TCP的流量拥塞控制
- 集成了TLS加密
- 多路复用
- 快速握手
- 此协议是最新推出的,只有最近新出的设备才配有此协议,但大家的老设备没坏,所以并不好大范围支持
到这里 HTTP协议的一些历史版本就介绍结束了。
3. 四次挥手
- 客户端向服务端发送断开连接请求
- 服务端接收到断开连接请求后,返回一个同意断开的响应,并进入到CLOSE_WAIT状态
- 服务端如果存在没有发送完毕的数据,会继续发送,进入LAST_ACK状态
- 客户端接收到服务端的应答,客户端进入CLOSE_WAIT状态持续2MSL,并向服务端发送确认应答。在2MSL时间后自动进入CLOSE状态,服务端在接收到客户端的确认应答也进入CLOSE状态。
这里的2MSL是一段时间,这段时间是数据包能够存活的有效时长,确保服务端接收到确认应答,因为有可能服务端因为网络问题而没有接收到确认应答,而一直处于等待状态。
后面就是拿到html、css等数据来到浏览器渲染,也就涉及 DOM树、OM树、RENDER树,页面排版之类的了,这里不继续絮叨。
结语
今天也是自己回顾总结了有关 HTTP 的一些知识点,这些都是个人观点,有不同看法,欢迎指正。大家一起加油!
转载自:https://juejin.cn/post/7404780384544833551