面试 | 当你输入URL到页面渲染出来中间发生了什么?
新的一篇,最近在学习 go 语言,现在很多大厂都在用 go 重构产品,这语言未来会比较火,双修 go ,以后也会更新一些 go语言方面的文章。
今天来聊一聊这道面试题:当你输入网站到页面渲染出来中间包的交互过程
流程DNS 域名解析
将域名转换为对应IP地址。
TCP连接
通过 IP 地址找到对应服务器,三次握手建立 TCP 连接。
发送 HTTP 请求
客户端封装发送 HTTP 请求包(应用层-网络层-传输层-数据链路层)
服务器响应请求返回 HTTP报文
服务器处理 http请求包(数据链路层-传输层-网络层-应用层),构建响应
浏览器解析渲染页面
客户端收到响应包,解析 HTML,构建 render树,根据render 树节点和 CSS的对应关系,进行布局,绘制页面
TCP断开连接
四次挥手断开连接。
你可能记得很多网址,但应该不会记得多少网站IP地址,DNS服务器就是帮助帮你记住网址对应的IP。
查询方式:递归查询,迭代查询
从浏览器缓存 --> 本地 host 文件 -->本地 DNS 解析器缓存 -->本地 DNS 服务器,这个过程中,任何一步找到了都会结束查找流程。
如果 DNS 服务器也无法查询到,则进行根域名服务器 -->顶级域名服务器 --> 权威域名服务器的迭代查询
DNS获取到请求域名服务器的IP地址之后,与服务器三次握手建立 TCP 连接
第一次握手:客户端将标志位 SYN 位为 1,seq为 X(X的值为 1-1234567 的随机值)的连接请求报文发出,进入SYN_SEND 状态,等待服务器确认
第二次握手:服务端收到SYN 为 1 的客户端连接请求报文后,需要对这个报文进行确认,服务端将标志位 SYN 与 ACK置为 1,设置 ack为 X+1, seq=Y(Y的值为 1-1234567 的随机值),发回给客户端,此时服务器进入 SYN_RECV状态
第三次握手:客户端收到服务器的 ACK+SYN 报文,将ack设置为 Y+1,向服务器发送 ACK报文。这个报文发送完毕之后客户端和服务器端都进入了 ESTABLISHED 状态
三次握手完成
备注:
ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0。TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。
SYN(SYNchronization):在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此, SYN置1就表示这是一个连接请求或连接接受报文。
FIN(finis)即完,终结的意思, 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。
补充:
路由寻址是什么?
客户端封装数据包,源地址为自己,目的地址为服务器 IP,通过 mac 地址表,走对应交换机接口,传输到路由器,根据路由器路由表找到每下一跳地址,进行相应数据转发,发送到服务器,服务器进行数据解封装处理。数据发回时同理为什么要三次握手?
"为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误"
客户端发送TCP连接请求报文,可是可能因为网络问题,客户端让该链接超时失效。但服务器收到此失效报文后,误认为该客户端请求连接,如果不采用三次握手,服务器发出确认,那么新的连接就建立了
客户端收到服务器的确认消息,并不会理睬也不会发送数据。
服务器以为连接已经建立,一直等待,就造成资源浪费
如果是三次握手,服务器收不到客户端返回来的确认报文,就知道客户端并没有要求建立连接
也避免了攻击者持续发送TCP连接请求包,耗尽服务器资源
TCP连接建立后,浏览器就可以利用 HTTP协议向服务器发送请求了。
HTTP请求报文主要由请求行、请求头、报文主体三部分组成
请求行:
由3部分组成,分别为:请求方法、URL(见备注1)以及协议版本,之间由空格分隔
请求方法包括GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE以及扩展方法,当然并不是所有的服务器都实现了所有的方法,部分方法即便支持,处于安全性的考虑也是不可用的
协议版本的格式为:HTTP/主版本号.次版本号,常用的有HTTP/1.0和HTTP/1.1
ps:
请求方法 GET 与 POST 之间有何区别?
"GET方法的数据参数是暴露在起始行的URL中的,而POST方法的数据参数是在报文主体中的。
GET方法相对来说没有POST安全,因为它的数据参数可以直接从URL中获取,但是GET的效率更高。
GET方法的数据参数大小有一定的限制(1024)(原因也是因为它的数据参数是放在URL中的),而POST对数据大小是没有限制的。
其实他们的本质区别是GET是从服务器上请求数据,而POST是向服务器发送数据
请求头:
Accept:告诉服务器当前浏览器能接受和处理的介质类型,*/*表示可接受所有类型。
Accept-Encoding:告诉服务器当前浏览器支持的内容编码。
Accept-Language:告诉服务器当前浏览器能接受和处理的语言。
Connection:keep-alive,告诉服务器在完成本次请求的响应后,保持该TCP连接不释放,等待本次连接的后续请求。这样可以减少打开关闭TCP连接的次数提升处理性能。另外的可选项是Close,表明直接响应接受完成后直接将其关闭。
Host:接受请求的服务器地址,可以是IP:端口号,也可以是域名
User-Agent:发送请求的应用程序名称
Content-Length:用于描述HTTP消息实体的传输长度。
Content-Type:内容类型,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件。
请求头部最后有一个空行,表示请求头部结束,后面就是请求正文了
请求正文:
可选,比如 GET 请求就没有请求正文
HTTP 相应报文主要由状态行、响应头部、响应正文三部分组成
状态行:
由协议版本、状态码、状态码描述组成
状态码:
1XX:参考信息
2XX:状态成功
3XX:用于重定向
4XX:客户端错误
5XX:服务器端错误
列几个常用的:
响应头:
与请求头类似:
Server:服务器应用程序软件的名称和版本
Content-Type:响应正文的类型(是图片还是二进制字符串)
Content-Length:响应正文长度
Content-Charset:响应正文使用的编码
Content-Encoding:响应正文使用的数据压缩格式
Content-Language:响应正文使用的语言
浏览器拿到响应文本后,解析HTML代码,请求js,css等资源,最后进行页面渲染,呈现给用户。页面渲染一般分为以下几个步骤:
(1)根据HTML文件解析出DOM Tree
(2)根据CSS解析出 CSSOM Tree(CSS规则树)
(3)将 DOM Tree 和 CSSOM Tree合并,构建Render tree(渲染树)(4)reflow(重排):根据Render tree进行节点信息计算(Layout)
(5)repaint(重绘):根据计算好的信息绘制整个页面(Painting)
数据传输完毕,四次挥手,断开连接
1、客户端向服务端发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(由浏览器告诉服务器,我请求报文发送完了,你准备关闭吧)
2、服务端向客户端发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(由服务器告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)
3、服务端向客户端发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(由服务器告诉浏览器,我响应报文发送完了,你准备关闭吧)
4、客户端向服务端发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(由浏览器告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)
还有什么问题,欢迎留言
以上~