为什么输入url就可以展现对应的页面呢?背后经历了什么?
总体为以下几个过程:
- DNS解析,将域名解析成Ip地址
- Tcp/Ip三次握手建立连接
- 浏览器向服务器发送http请求
- 服务器处理请求并返回http报文
- 浏览器解析渲染页面
- tcp四次挥手断开连接
一、DNS域名解析
??????在浏览器输入网址(URL)后,首先要经过域名解析,因为浏览器只能通过IP地址找到对应的服务器,输入的是域名,那么就需要解析成IP地址。
过程
??????1、浏览器先检查自身缓存中有没有被解析过的这个域名对应的 IP 地址。 ??????2、浏览器缓存中没有命中,浏览器会检查操作系统缓存中有没有对应的已解析过的结果。(在 Windows 中可通过 C 盘里一个叫 hosts 的文件来设置,如果你在这里指定了一个域名对应的 IP 地址,那浏览器会首先使用这个 IP 地址。) ??????3、至此还没有命中域名,会请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约 80% 的域名解析到这里就会完成。 ??????4、LDNS 仍然没有命中,就直接跳到 Root Server 域名服务器请求解析。 ??????5、根域名服务器返回给 LDNS 一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org 等)地址。 ??????6、此时 LDNS 再发送请求给上一步返回的 gTLD Server。 ??????7、接受请求的 gTLD Server 查找并返回这个域名对应的 Name Server 的地址,这个 Name Server 就是网站注册的域名服务器。 ??????8、Name Server 根据映射关系表找到目标 IP,返回给 LDNS。LDNS 缓存这个域名和对应的 IP。 ??????9、LDNS 把解析的结果返回给用户,用户根据 TTL 值缓存到本地系统缓存中,域名解析过程至此结束。
二、Tcp三次握手建立连接
目的
??????为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
过程
- 第一次握手,由浏览器发起,告知服务器,我要发送请求了(浏览器发送一个带SYN=1,Seq=x的数据包到服务器)
- 第二次握手,由服务器发起,告知浏览器,我准备接收了,你发送吧(服务器发回一个带SYN=1,ACK= X+1,Seq=Y的响应包以示传达确认信息)
- 第三次握手,由浏览器发起,告知服务器,我马上就要发了,你准备好接收吧(浏览器再传回一个带ACK=Y+1,Seq=Z)
三、浏览器向服务器发送http请求
?????? 一个 HTTP 请求报文由请求行(request line)、请求头部(headers)、空行(blank line)和请求数据(request body)4 个部分组成。
请求行
请求行包括请求方法、URL、协议版本如:
POST /detanx HTTP/1.1
请求头
请求头包含请求的附加信息,由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。如:
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
请求数据
可以承载多个请求参数的数据,包含回车符、换行符和请求数据,并不是所有请求都具有请求数据,例如某些 get 请求。如:
username=detanx&password=Aa123456
四、服务器处理请求并返回http报文
HTTP 响应报文由状态行(status line)、相应头部(headers)、空行(blank line)和响应数据(response body)4 个部分组成。
状态行
状态行由 3 部分组成,分别为:协议版本、状态码、状态码扫描。其中协议版本与请求报文一致,状态码描述是对状态的简单描述。如:
HTTP/1.1 200 OK
响应头
响应头与请求头一样,只是与请求头包含的附加信息有所不同。如:
Date: Sun, 17 Mar 2013 08:12:54 GMT
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json
响应数据
根据请求类型的不同,响应的数据格式也有所不同,有可能是二进制文件流、JSON 对象、字符串、HTML 文件等。如:
{name: '汨汨'}
五、浏览器解析渲染页面
步骤
- 根据 HTML 解析出 DOM 树
- 根据 CSS 解析生成 CSS 规则树
- CSS 规则树附着到 DOM 树上 ,构造生成渲染(Render Tree)树
- 布局layout:根据渲染树计算每一个节点的信息(重排)
- paint : 根据计算好的信息绘制整个页面(重绘)
回流和重绘
回流
??????当 Render Tree 中的一部分(或全部)因为元素的几何属性、规模尺寸、布局、隐藏等改变而需要重新构建。每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建 Render Tree。
重绘
??????当 Render Tree 中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如 background-color、color等。 回流必将引起重绘,而重绘不一定会引起回流。
六、 tcp四次挥手断开连接
(主动方 --> 浏览器,被动方 --> 服务器)
- 第一次挥手:主动方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。
- 第二次挥手:被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机主动方进入 FIN_WAIT_2 状态。
- 第三次挥手:被动方向主动方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。
- 第四次挥手:主动方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到主动方的报文段以后关闭连接。主动方等待一定时间未收到回复,则正常关闭。
|