浏览器地址栏输入url到看到页面,大概分为以下几个过程
- 输入url并回车
- 浏览器查找当前url是否有缓存,并解析ip
- 根据ip建立TCP连接,三次握手
- 浏览器发起请求并接收服务端响应
- 浏览器解析渲染页面
- 关闭TCP连接,四次挥手
一般来说,URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号。所以,请记住以下结论
- 网址路径的编码,用的是utf-8编码
- 查询字符串的编码,用的是操作系统的默认编码
- GET和POST方法的编码,用的是网页的编码
- 在Ajax调用中,IE总是采用GB2312编码(操作系统的默认编码),而Firefox总是采用utf-8编码
- 输入url后,浏览器会先查找本地hosts文件是否有这个网址映射关系,有就调用ip地址映射,完成域名解析。
- 如果没有找到,则在操作系统缓存中查找本地DNS解析器缓存,有则返回
- 如果没有找到,则在路由器缓存中进行查找,有则返回
- 如果没有找到,则按ISP(运营商)DNS缓存、根域名服务器、顶级域名服务器、主域名服务器的顺序,逐步读取缓存,直到拿到IP地址
为什么必须三次握手:为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
三次握手过程:
- 客户端发送一个syn包:即带有 SYN=1,Seq=随机数 的数据包到服务器端口,并进入SYN_SENT状态,等待服务器确认
(第一次握手,由浏览器发起,告诉服务器我要发送请求了) - 服务器收到syn包,必须确认客户的SYN,同时发回一个带 SYN=1, ACK=客户端Seq随机数+1, Seq=随机数 的响应包以示传达确认信息,即SYN+ACK包,此时服务器进入SYN_RECV状态
(第二次握手,由服务器发起,告诉浏览器我准备接受了,你发送吧) - 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,即回传一个带 ACK=服务器Seq随机数+1, Seq=随机数 的数据包,代表“握手结束”
(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接收吧)
先了解一下和缓存相关的请求响应头
Expires
响应头,代表该资源的过期时间。
Cache-Control
请求/响应头,缓存控制字段,精确控制缓存策略。
If-Modified-Since
请求头,资源最近修改时间,由浏览器告诉服务器。
Last-Modified
响应头,资源最近修改时间,由服务器告诉浏览器。
Etag
响应头,资源标识,由服务器告诉浏览器。
If-None-Match
请求头,缓存资源标识,由浏览器告诉服务器。
配对使用的字段:
If-Modified-Since 和 Last-Modified
Etag 和 If-None-Match
浏览器首次加载资源成功时,服务器返回200,此时浏览器不仅将资源下载下来,而且把response的header一并缓存。
下一次加载资源时,首先要经过强缓存的处理,cache-control的优先级最高,比如cache-control:no-cache,就直接进入到协商缓存的步骤了
如果cache-control:max-age=xxx,就会先比较当前时间和上一次返回200时的时间差,如果没有超过max-age,命中强缓存,不发请求直接从本地缓存读取该文件(这里需要注意,如果没有cache-control,会取expires的值,来对比是否过期),过期的话会进入下一个阶段,协商缓存
协商缓存阶段,则向服务器发送header带有If-None-Match和If-Modified-Since的请求,服务器会比较Etag,如果相同,命中协商缓存,返回304。如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200。
协商缓存第二个重要的字段是,If-Modified-Since。如果客户端发送的If-Modified-Since的值跟服务器端获取的文件最近改动的时间,一致则命中协商缓存,返回304。不一致则返回新的last-modified和文件并返回200。
- 解析HTML,构建DOM树
- 解析CSS,生成CSS规则树
- 合并DOM树和CSS规则,生成render树
- 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
- 绘制render树(paint),绘制页面像素信息
- 浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite)显示在屏幕上。
reflow:也称作layout,中文叫回流,一般意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树,这个过程称为reflow。
repaint:中文重绘,意味着元素发生的改变只是影响了元素的一些外观之类的时候(例如:背景色,边框颜色,文字颜色等),此时只需要应用新样式绘制这个元素就可以了。
- 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧) - 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了) - 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧) - 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)



