简而言之,发生了以下过程:DNS域名解析、建立TCP链接、浏览器请求获取页面html、接受响应结果解析html渲染页面、断开TCP链接
具体来说:
1.DNS域名解析:
通过DNS多级缓存解析域名对应的 WEB 服务器的实际IP地址。 缓存查找顺序如下:浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,公共的域名(如根域名服务器缓存等),查找的过程还是一个递归查询的过程。
2.建立TCP链接:(三次握手)
客户端发送syn包(Seq=x)到服务器请求连接,并进入SYN_SEND状态,等待服务器确认;
服务器收到连接请求后,返回确认同时发送客户的SYN(ack=x+1)和自己的SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
通俗点说:
- 客户端:你能接收到我的消息吗?
- 服务端:可以的,那你能接收到我的回复吗?
- 客户端:可以,那我们开始传输吧。
为什么俩次不行:
a.服务器无法知道自己的序号是否被确认
b.不能防止客户端失效的请求报文段被服务器接收而出现错误,导致服务端一直等待,出现资源浪费
为什么不是四次握手:
三次足够,四次没必要。
3.浏览器请求获取页面html
注意:HTTP的端口为80/8080,而HTTPS的端口为443
浏览器向服务器的 ip 地址发送相应的 http get 请求页面html,发起http请求的过程主要是组装http报文并将报文发向指定地址的过程。常用的方法有: GET
, POST
, PUT...
4.服务器返回响应结果
对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,HTTP报文也分成三份,状态码 ,响应报头和响应报文。
浏览器解析渲染页面
解析html:
- 浏览器下载 HTML 数据,将html文档解析成为一个个
标签
,这些标签组成了树状结构
- 如果解析到
style
标签则开始解析css,如果解析到link标签则先异步下载,完成后解析css。 - 如果遇到
script
标签,判断是行内写法则直接解析执行,如果是src引入则同步下载
脚本文件,下载完成立即执行
,注意这里下载过程是阻塞
的,其他流程都会等下载完成后执行。
渲染页面:
解析完成后,浏览器引擎会根据DOM树和CSS规则树来构造渲染树,并开始渲染并绘制页面这个过程涉及两个比较重要的概念回流和重绘。
5.断开TCP链接:(四次挥手)
1.客户端认为数据发送完成,向服务端发送一个FIN释放连接请求。
2.服务端收到释放请求后告诉应用层要释放TCP连接,发送ACK进入close-wait状态(TCP为双向连接,此时服务端不再接受客户端的数据,但可以发送数据给客户端)
3.服务端此时继续发送剩下的数据,完毕后向客户端发送连接释放请求,进入last-ack状态等待客户端的确认。
4.客户端收到释放请求后想服务端发送ACK确认应答,此时客户端进入time-wait状态持续2msl(报文段最大生存期),若该时间段内没有服务端的重发请求就进入closed状态,当服务端收到确认应答后也进入closed状态。
补充:若协议是https则会做加密
HTTPS = HTTP + 加密 + 认证
- 要先申请CA证书,并安装在服务器上(一个文件,配置nginx支持监听443端口开启ssl并设置证书路径)
- 浏览器发送请求;
- 网站从浏览器发过来的加密规则中选一组自身也支持的加密算法和hash算法,并向浏览器发送带有公钥的证书,当然证书还包含了很多信息,如网站地址、证书的颁发机构、过期时间等。
- 浏览器解析证书。
- 验证证书的合法性。如颁发机构是否合法、证书中的网站地址是否与访问的地址一致,若不合法,则浏览器提示证书不受信任。
- 若合法,浏览器会生成一串随机数的密码(即密钥),并用证书中提供的公钥加密。
- 使用约定好的hash计算握手消息,并使用生成的随机数(即密钥)对消息进行加密,最后将之前生成的所有消息一并发送给网站服务器。
- 网站服务器解析消息。用已有的私钥将密钥解密出来,然后用密钥解密发过来的握手消息,并验证是否跟浏览器传过来的一致。然后再用密钥加密一段握手消息,发送给浏览器。
- 浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。