浏览器输入一个地址到请求返回,经历的过程
总共7个步骤
解析域名--->三次握手--->发送请求--->响应请求--->返回请求--->解析渲染
一、解析域名
当我们输入网址,浏览器在生成消息之前,需要解析网址,浏览器是如何解析网址的?我们随意输入一个字符串,浏览器肯定不会搭理我们。因此,我们输入的网址(URL)必须按照一定的格式才行。
我们常见的url都是以http://+字符串,其实还有以“ftp:”,“file:”,“mailto:”等开头。
用http协议访问web服务器:http://user:password@www.glasscom.com:80/dir/file1.htm
用FTP协议下载和上传文件
ftp://user:password@ftp.glasscom.com:21/dir/file1.htm
读取客户端计算机本地文件
file://localhost/c:/path/file1.zip
从上面的三个例子,我们可以总结出url的结构:
解析过程:
1.浏览器访问www.baidu.com,询问本地DNS服务器是否缓存了该网址解析后的IP地址
2.如果本地DNS服务器没有缓存的话,就去root-servers-net根据服务器查询该网址对应的ip地址
3.根据服务器返回顶级域名服务器的网址gtld-servers.net,然后本地DNS服务器去顶级域名服务器查询该网址对应的IP地址
4.顶级域名服务器返回www.baidu.com主区域服务器的地址,然后本地DNS服务器去www.baidu.com主区域服务器查询此域名对应的ip地址
5.本地DNS服务器拿到www.baidu.com解析后的IP地址后,缓存起来以便查,然后把解析后的IP地址返回给浏览器
二、三次握手---TCP的建立连接
主机浏览器通过DNS解析得到了目标服务器的IP地址后,与服务器建立TCP连接,即三次握手:
1.浏览器所在的客户机向服务器发出连接请求报文;
2.服务器接收报文后,同意建立连接,向客户机发出确认报文;
3.客户机接收到确认报文后,再次向服务器发出报文,确认已接收到确认报文;
4.此时客户机与服务器之间的TCP连接建立完成,开始通信
三、发送请求
http请求消息也是有格式要求的,一个http请求消息包括请求行、请求头、空行和消息体四部分。
请求中包含访问的URL,也就是http://www.baidu.com/ ,KeepAlive,长连接,还有User-Agent用户浏览器操作系统信息,编码等。值得一提的是Accep-Encoding和Cookies项。Accept-Encoding一般采用gzip,压缩之后传输html文件。Cookies如果是首次访问,会提示服务器建立用户缓存信息,如果不是,可以利用Cookies对应键值,找到相应缓存,缓存里面存放着用户名,密码和一些用户设置项。
应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。
协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,它们两会接受应用层的委托执行收发数据的操作。
协议栈的下面一半是用 IP 协议控制网络包收发操作,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP 负责的。
请求到达Web服务器
1.到达服务器的网络包本质是电信号或者光信号,因此首先是网卡将信号转换为数字信号。
2.当网络包转交到协议栈时,IP 模块会首先开始工作,检查 IP 头部,判断是不是发给自己的。
3.IP模块再将包转交给TCP或者UDP模块。
4.Web服务器将请求的URI转换为实际的文件名
四、响应请求
状态行 + 响应头 + 响应实体内容。返回状态码200 OK,表示服务器可以响应请求,返回报文。
常见响应状态码
1. 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码。
100 (继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。
2. 2xx (成功) 表示成功处理了请求的状态代码。
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 (部分内容) 服务器成功处理了部分 GET 请求。
3. 3xx (重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4. 4xx(请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
400 (错误请求) 服务器不理解请求的语法。
401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 无法使用请求的内容特性响应请求的网页。
407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。
5. 5xx(服务器错误) 这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
常用标准响应头
Access-Control-Allow-Origin 指定哪些站点可以参与跨站资源共享
Accept-Patch 指定服务器支持的补丁文档格式,适用于http的patch方法
Accept-Ranges 服务器通过byte serving支持的部分内容范围类型
Age 对象在代理缓存中暂存的秒数
Allow 设置特定资源的有效行为,适用方法不被允许的http 405错误
Alt-Svc 服务器使用"Alt-Svc"(Alternative Servicesde的缩写)头标识资源可以通过不同的网络位置或者不同的网络协议获取
Cache-Control 告诉服务端到客户端所有的缓存机制是否可以缓存这个对象,单位是秒
Connection 设置当前连接和hop-by-hop协议请求字段列表的控制选项
Content-Disposition 告诉客户端弹出一个文件下载框,并且可以指定下载文件名
Content-Encoding 设置数据使用的编码类型
Content-Language 为封闭内容设置自然语言或者目标用户语言
Content-Length 响应体的字节长度
Content-Location 设置返回数据的另一个位置
Content-MD5 设置基于MD5算法对响应体内容进行Base64二进制编码
Content-Range 标识响应体内容属于完整消息体中的那一部
Content-Type 设置响应体的MIME类型
Date 设置消息发送的日期和时间
ETag 特定版本资源的标识符,通常是消息摘要
Expires 设置响应体的过期时间
Last-Modified 设置请求对象最后一次的修改日期
Link 设置与其他资源的类型关系
Location 在重定向中或者创建新资源时使用
P3P 以P3P:CP="your_compact_policy"的格式设置支持P3P(Platform for Privacy Preferences Project)策略,大部分浏览器没有完全支持P3P策略,许多站点设置假的策略内容欺骗支持P3P策略的浏览器以获取第三方cookie的授权
Pragma 设置特殊实现字段,可能会对请求响应链有多种影响
Proxy-Authenticate 设置访问代理的请求权限
Public-Key-Pins 设置站点的授权TLS证书
Refresh "重定向或者新资源创建时使用,在页面的头部有个扩展可以实现相似的功能,并且大部分浏览器都支持
Retry-After 如果实体暂时不可用,可以设置这个值让客户端重试,可以使用时间段(单位是秒)或者HTTP时间
Server 服务器名称
Set-Cookie 设置HTTP Cookie
Status 设置HTTP响应状态
Strict-Transport-Security 一种HSTS策略通知HTTP客户端缓存HTTPS策略多长时间以及是否应用到子域
Trailer 标识给定的header字段将展示在后续的chunked编码的消息中
Transfer-Encoding 设置传输实体的编码格式,目前支持的格式: chunked, compress, deflate, gzip, identity
Upgrade 请求客户端升级协议
Vary 通知下级代理如何匹配未来的请求头已让其决定缓存的响应是否可用而不是重新从源主机请求新的
Via 通知客户端代理,通过其要发送什么响应
Warning 实体可能会发生的问题的通用警告
WWW-Authenticate 标识访问请求实体的身份验证方案
X-Frame-Options 点击劫持保护:
deny frame 中不渲染
sameorigin 如果源不匹配不渲染
allow-from 允许指定位置访问
allowall 不标准,允许任意位置访问
对于大型网站存在多个主机站点,往往不会直接返回请求页面,而是重定向。返回的状态码就不是200OK,而是301,302以3开头的重定向码,浏览器在获取了重定向响应后,在响应报文中Location项找到重定向地址,浏览器重新第一步访问即可。
重定向的好处:
1、负载均衡:利用一个前端服务器接受请求,然后负载到不同的主机上,可以大大提高站点的业务并发处理能力。
2、导入流量:由于baidu.com,www.baidu.com会被搜索引擎认为是两个网站,造成每个的链接数都会减少从而降低排名,永久重定向会将两个地址关联起来,搜索引擎会认为是同一个网站,从而提高排名。
五、释放连接
TCP释放连接---4次挥手
1.浏览器所在主机向服务器发出连接释放报文,然后停止发送数据;
2.服务器接收到释放报文后发出确认报文,然后将服务器上未传送完的数据发送完;
3.服务器数据传输完毕后,向客户机发送连接释放报文;
4.客户机接收到报文后,发出确认,然后等待一段时间后,释放TCP连接;
六、返回响应
七、解析渲染
页面的渲染阶段流程
1.解析HTML生成DOM树。
2.解析CSS生成CSSOM规则树。
3.将DOM树与CSSOM规则树合并在一起生成渲染树。
4.遍历渲染树开始布局,计算每个节点的位置大小信息。
5.将渲染树每个节点绘制到屏幕。
浏览器的渲染主要步骤:
DOM树的构建:渲染引擎解析HTML文档,并将HTML文档包含的元素转化为一个个DOM,并构建一个DOM树,若如果遇到< link href ="..">和< script src ="..">这种外链加载 CSS 和 JS 的标签,浏览器会启用别的线程下载这些静态资源。在 head 中遇到 JS 文件时,HTML 的解析会停下来,等 JS 文件下载结束并且执行完,HTML 的解析工作再接着来,防止 JS 修改已经完成的解析结果,JS的解析会阻塞DOM的解析。
CSSOM:引擎开始解析来自CSS文件或直接嵌在HTML页面中的CSS样式数据,这些样式信息包含了颜色,大小,位置等属性。DOM的解析和CSS的解析是互不影响的,两者是并行的,但是由于render tree的生成是依赖DOM Tree和CSSOM Tree的,因此CSS必然会阻塞DOM的渲染。更为严谨一点的说,CSS会阻塞render tree的生成,进而会阻塞DOM的渲染。
渲染树:将 DOM 和 CSSOM 整合成 RenderTree ,渲染引擎会给每个DOM元素安排精确的样式,大小,坐标等,并根据坐标显示在屏幕上。
为了更好的用户体验,渲染引擎会尽量在屏幕上尽快显示内容。在开始构建和布局渲染树之前,它不会等到所有 HTML 都被解析。部分内容将被解析和显示,而该过程将继续处理来自网络的其余内容。
渲染引擎是单线程工作的,除了网络操作,其他所有的都是单线程的。在Firefox和Safari,它们自己就是主线程,而Chrome就是每个tab处理主线程。网络操作则由多个并列线程去执行,但数量也是受限的,一般在2-6个。浏览器的主线程是一个无限的事件循环,而且一直保持进程alive,一直等着各种事件(例如绘画事件,布局事件),并处理他们。