大前端网络专题篇之HTTP
1️⃣、请简述浏览器输入 URL 地址以后所发生的事情
浏览器解析URL
将url中元素拆分出来
URL格式,重要的是scheme,host和path
按照URL格式拆分:
请求需要访问
www.lab.glasscom.com
域下的dir1
目录下的file1.html
文件。几个例子:
如果是
http://www.lab.glasscom.com/
,表示访问根目录下的默认文件(index.html
之类的,根据服务器配置信息决定)如果是
http://www.lab.glasscom.com/index
,如果存在index
文件就当做文件名处理,如果没有就当做目录名
生成http请求消息
略
向DNS服务器查询web服务器IP地址
补充:
浏览器不具备将消息发送到网络中的能力,要借助操作系统完成。这时候要知道通信对象的IP地址(不直接使用域名确定通信对象是因为运行效率问题,IP地址长度为32比特,4字节。域名最短几十字节,最多255字节)
DNS 中的域名都是用句点来分隔的,比如 www.lab.glasscom.com,这里的句点代表了不同层次之间的界限(相当于公司里面的组织结构不用部、科之类的名称来划分,只是用句点来分隔而已 ),域名中越靠右的层级越高。每个域的信息都存放在相应层级的 DNS 服务器中。
以为 www.lab.glasscom.com 为例,com
和jp
上还有一层域,成为根域。一般书写时候被忽略,明确表示的话是这样www.lab.glasscom.com.
DNS 服务器会从域名与 IP 地址的配置文件中(域名与IP对应的映射表)查找相应的记录,并返回 IP 地址。
如果没找到,那么会寻找相应的 DNS 服务器并获取 IP 地址
如果没找到,那么会将查询消息转发到根域DNS服务器
比如查询 www.lab.glasscom.com ,过程如下:
1)先找到最近的DNS服务器(客户端配置的),找到了就返回
2)没有找到的话,就将查询消息转发到根域DNS服务器
3)根域返回了com
域的IP
,说你去那里问问吧
4)com
域返回了glasscom
域的IP
,说你去问问吧
5)glasscom
域返回了lab
域的IP
,说你去问问
6)重复上面步骤, 最后找到了,返回IP
。
创建套接字
创建套接字,套接字实体可以理解为存放通信对象的ip地址,端口号,通信操作的进行状态等的内存空间,协议栈根据套接字中的控制信息工作。看一下套接字内容
本地套接字与服务端套接字连接
也就是三次握手
1)客户端创建一个包含 表示开始数据收发操作的控制信息头部,在这里客户端知道了要连接服务器的哪个套接字,将头部控制位的SYN
设置为 1 表示连接,并且设置初始化序号。创建好以后委托IP
模块发送
2)IP
模块发送后,通过网络传输,服务器上的IP
模块将收到的数据传输给TCP
模块,服务器根据TCP
头部信息找到对应套接字,以后服务器TCP
模块返回响应,设置SYN
为 1,服务端也会初始化一个序列号,同时设定ACK
为客户端初始化序列号加 1,表示确认,以后委托IP
模块向客户端返回响应
3)网络包返回到客户端,通过IP
模块到TCP
模块,这时候向套接字写入服务器IP
地址,端口号等,客户端设置ACk
为服务端初始化序列号加 1,返回服务器),之后进入随时可以收发数据的阶段
传输数据,数据收发阶段
协议栈一收到数据不会立马发送,与长度优先
和时间优先
有关。而对较大HTTP
请求消息数据进行拆分
Mtu:最大传输单元
Mss:最大分段大小,mtu减去tcp和ip头部
TCP
具有确认对方是否收到网络包,并且没收到会进行重新发送的功能,那么是怎么确认的呢?(图中初始化序号为1,但是实际情况一般是随机一个初始序列号。)
TCP
模块在拆分数据的时候,计算好每一块相对于从头开始的第几个字节(也就是序号),将字节数加在TCP
头部。数据的长度也会告知接收端,不过长度不放在头部(整个网络包长度减去头部长度,就是数据长度)接收方可以通过这样计算数据长度。通过这些信息接收方就能知道数据是否有遗漏。接收方接到后,会把目前接收到的数据长度加起来,算出多少字节,然后把这个数值加 1 后,放在TCP
头部的ACK
号中返回客户端,表示确认。而发送的包会保存在发送缓冲区内,如果没有收到某些包对应的ACK
号,就会重新发送。
- 滑动窗口:发送一个包,不等待
ACK
返回,直接发送后续的包,这样能减少等待ACK
号的时间浪费。
- 滑动窗口与接收缓冲区:接收方会告诉发送方自己能接收多少数据,发送方根据这个值对发送数据控制。当接收方收到包以后,会将数据存放在接收缓冲区,并执行接收操作,完成之后释放接收缓冲区的空间,接收方会通过
TCP
头部告诉发送方自己能接收的数据量
那么在什么时机点返回ACK号和更新窗口的时机,接收方在发送ACK号和滑动窗口更新时,并不会马上把包发送出去,会等待一段时间,这样可以把两种通知合并到一个包里发送(当需要连续发送多个ACK号的时候也可以减少包的数量,在固态发四部分最后一个ACK号就可以了)。
IP
与以太网的包收发操作
TCP
模块在执行连接、收发、断开各阶段操作的时候,都需要委托IP
模块将数据封装成包发送给通信对象。
- 包的基本结构
- TCP/IP包
MAC
头部与IP
头部的作用:
发送方将包的目的地,就是要访问的服务器IP
地址写入IP
头部中(地址是由TCP
模块告知的,TCP
在执行链接的时候从应用程序获得的)。IP
协议根据这个地址查找包传输方向,从而找到下一个路由器的位置,之后委托以太网协议将包传输过去。这时候,IP
协议会查找下一个路由器的以太网地址(MAC
地址),并将这个地址写入MAC
头部,以太网协议就知道要将包发到哪一个路由器上。
到达路由器后,会查出接下来发往哪个路由器,会查出下一个路由器的MAC
地址,并记录到MAC
头部中(路由器在收到包的时候MAC
头部被舍弃,再次发送的时候加上包含新的MAC
地址的新MAC
头部)
IP
模块将TCP
头部和数据块看作一整块二进制数据,收发操作的时候不关心其中内容,也不关心包的丢包与乱序。
将IP
包转换成电或光信号发送出去,IP
生成的网络包只是存放在内存中的数组信息,无法直接发送,需要转换。
MAC
模块把包取出,给网络包增加3个控制数据,在开头加上报头(用于确认包的读取时机)和起始帧分界符(SFD
,用来确认帧的起始位置),在末尾加上用于检测错误的帧校验序列
- 从包头开始将数字信息按每个比特转成电信号,之后由
PHY(MAU)
将信号转换为可在网线上传输的格式,并通过网线发送出去
信号在网线和集线器中传输
从计算机发送出来的网络包会通过集线器、路由器、交换机等设备被转发。
请求到达Web服务器,响应返回浏览器
服务器概览
服务器需要同时和多个客户端通信,一个程序处理多个客户端请求是很难的(需要把握每一个客户端计算机进行通信),因此一般做法的是每一个客户端连接,就启动一个新的服务器程序(也可能是事先启动的),确保服务器程序和客户端是一对一的状态。
- 服务器接收操作
网卡将接受到的信号(光信号或电信号)转成数字信息,根据包末尾的校验序列来校验错误,如果有错误,接收到的包就是无效的,需要被丢弃。如果包有效就检查MAC头部中的接收方MAC地址,看这个包是不是发给自己的。不是就丢弃。
- 服务器程序解释请求消息并作出相应
获取HTTP请求消息,服务器程序会根据收到的请求消息中的内容进行相应的处理,并且生成响应消息,将响应消息交给协议栈,协议栈将数据分成多个网络包,然后加上头部发送出去,它们经过交换机和路由器的转发,最终到达客户端。
- 浏览器接收响应消息
服务器发送的响应消息被分成多个包发送给客户端,客户端接收数据之后把信号还原成数字信息。然后把消息转交给浏览器。
渲染
构建DOM树
构建CSSOM树
构建渲染树
回流
重绘
断开管道并删除套接字
四次挥手:
刚开始双方都处于 establised 状态
1)客户端发送一个数据包,带有 FIN标记,报文中会指定一个序列号,此时客户端属于 FIN_WAIT1状态(FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认)
2)服务器接收到,返回一个数据包带有 ACK标记(客户端的序列号 + 1 的值),此时服务端处于 CLOSE_WAIT状态(CLOSE-WAIT - 等待从本地用户发来的连接中断请求)。
3)服务端也想断开连接,发送数据包,带有 FIN标记,报文中会指定一个序列号,此时服务端处于 LAST_ACK 的状态(LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认)
4)客户端接收到,返回一个数据包带有 ACK标记(服务器的序列号 + 1 的值),此时客户端处于 TIME_WAIT 状态(TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认),一段时间之后进入 CLOSED 状态(CLOSED - 没有任何连接状态;)
之后套接字
就没有作用了,会等待一会后删除。
补充
UDP协议与TCP协议区别
TCP
会管理发送和确认进度,如果漏掉包,没有收到就会重新发送,收发之前需要建立和断开连接的步骤。
UDP
数据很短,一个包就能装下,不用考虑哪个包未收到,重新发送也只是发一个包而已,收到的数据会被当成回复,就不用专门接收确认包。也就是说它没有接收确认,窗口等机制,收发之前也不需要建立和断开连接。只需要从应用程序中取出数据,加上UDP
头部,以后交给IP
发送就可以了,对于错误与丢包一概不管,但是没有收到回复的时候,应用程序会注意到就会重发。
2️⃣、请列举常见的 HTTP 状态码并介绍它们的含义,至少五个以上。
101 服务器将遵从客户的请求转换到另外一种协议
200 OK 请求被正常处理
301 Moved Permanenlty 永久性重定向
302 Found 临时性重定向
301与302的区别:
访问URI的时候,第一次访问某地址状态码为301,根据Location头部重定向到新的页面,之后再访问这个地址,是直接访问Location头部的地址,不会访问原地址,比如第一次访问 www.qinhanwen.xyz/ 通过Location重定向到www.qinhanwen.xyz/new ,new的地址会被记录到缓存中,之后每次访问都直接访问这个地址,不再访问 www.qinhanwen.xyz/ (在没有清理缓存的情况下)
第一次访问状态码是302时,根据Location重定向。之后访问原地址,也根据Location重定向。就是每次都访问 www.qinhanwen.xyz/ ,在通过Location重定向
304 Not Modified 协商缓存
401 Unauthorized 认证失败
403 Forbidden 访问被拒绝
404 Not Found 无法找到请求的资源
500 Internal Server Error 服务端执行请求错误
503 Services Unavailable 服务器超负荷或者停机维护
3️⃣、请列举常见的 HTTP 头部并介绍它们的作用,至少五个以上。
https://qinhanwen.github.io/2019/02/27/%E5%B8%B8%E8%A7%81http%E5%A4%B4%E9%83%A8/
4️⃣、请列举常用的 HTTP 方法,并介绍 Get 与 Post 请求之间的区别。
常见方法:get 、post、 options、delete、put、 head
区别:
区别 | get | post |
---|---|---|
缓存 | 能被缓存 | 不能被缓存 |
安全性 | 相对post较低,参数直接拼接在url上 | 在网络节点上捉包,就能完整地获取数据报文 |
长度限制 | 对 URL 限制的大多是浏览器和服务器的原因(不同浏览器不一样),本身没有限制 | 无限制 |
编码类型 | application/x-www-form-url | encodedapplication/x-www-form-urlencoded 或 multipart/form-data |
GET 和 POST 只是 HTTP 协议中两种请求方式(异曲同工),而 HTTP 协议是基于 TCP/IP 的应用层协议,无论 GET 还是 POST,用的都是同一个传输层协议,所以在传输上,没有区别,只是浏览器厂家根据约定,做得限制而已。
5️⃣、请分别介绍 Cookie 和 Session 的作用及它们之间的区别。
Cookie:
1)客户端与服务端都可以设置cookie,不同域只能看到自己域下的cookie。
2)cookie默认不会跨域,发送请求的时候,机器会查看与域名有关的cookie,如果存在就一起发送到服务器,不存在就不发送。
3)cookie需要跨域的话,AJAX的withCredentials设置为开启,并且服务器设置Access-Control-Allow-Credentials: true
。客户端才可以发送cookie,服务端设置cookie才会被客户端接受。
4)跨域的时候传递cookie,Access-Control-Allow-Origin
不能是*
号。
5)存放在客户端
Session
1)存放在服务器上,由服务端保持状态,但是也需要客户端保存一个标识
2)服务器使用一种类似于散列表的结构来保存信息。
3) 当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id)。
补充:
为什么需要三次握手?
第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。