从输入URL到页面展示中的知识点

7 篇文章 0 订阅
3 篇文章 0 订阅

当我们输入一个网址,到浏览器呈现出页面这段时间内到底发生了什么事?

这是面试常考题,总体来说经历了以下几个过程。

1.浏览器输入网址并按下回车按钮
2.浏览器查找当前的url是够存在缓存,并比较缓存是否过期
3.域名解析URL对象的IP
4.将根据IP和服务器建立TCP连接(三次握手)
5.HTTP发起请求。
6.服务器处理请求并返回请求报文,浏览器接受HTTP响应。
7.构建DOM树,渲染页面
8.关闭TCP连接.(四次挥手)

但这只是很肤浅的回答,面试官一般都会在其中再深入问你其中的过程。所以我在这一一聊一下每个过程发生了什么。

1.浏览器输入网址并按下回车按钮

 

2.浏览器查找当前的url是够存在缓存,并比较缓存是否过期

url请求过程,浏览器进程会进行进程通信(IPC)把url请求发送给网络进程。网络进程会查找本地缓存是否有缓存资源,如果有则将资源返回给浏览器进程,没有则直接网络请求资源,进行请求前,还会通过DNS解析,以获取请求域名服务器的IP地址。

当输入网址之后,首先进行的就是域名解析。在通过传统的DNS服务器解析之间,其会先进行两次缓存检查。
第一次检查:浏览器检查。浏览器检查缓存中有没有该域名对应解析过的IP地址,如果有的话,则解析结束。
第二次检查:操作系统缓存检查。浏览器会查找系统中是否有该域名对应的DNS解析结果,有的话,解析结束。
如果还是没有找到解析过url的IP地址的话,会一层一层的向上查找DNS服务器解析,直到找到为止。
浏览器缓存 -》系统缓存 -》路由器缓存 -》ISP DNS缓存 -》 递归搜索

 

3.域名解析URL对象的IP

 

4.将根据IP和服务器建立TCP连接(三次握手)

为什么采用TCP协议而不是建立UDP协议呢?先聊下TCP和UDP的区别

TCP和UDP的区别

UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接对象个数支持一对一,一对多,多对一和多对多交通通信只能是一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅8字节首部最小20字节,最大60字节
使用场景使用与实时应用适用于要求可靠传输的应用

TCP三次握手

第一次握手:建立连接时,客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,并等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN,同事自己也要发送有一个SYN包(ack=x+1,seq=y),此时服务器进入SYN_RECV状态。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),客户端和服务器都进入到ESTABLISHED状态。
在这里插入图片描述
思考:如果建立连接之后,客户端出了故障怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等待下去,白白浪费资源。服务器每收到一次客户端的请求后都会重置该计时器,时间通常设置为2个小时,若两小时后还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然响应,服务器就认为客户端除了故障,接着就主动关闭连接。

 

5.HTTP发起请求。

当我们建立连接之后发送一个静态资源请求的时候,浏览器会先查看该该资源是否有缓存,再确定下一步的操作。所以我们聊一下浏览器的缓存机制!

浏览器缓存机制

首先,缓存分为两种:强缓存协商缓存

强缓存

强缓存判断是否缓存的依据来自于是否超出某个时间或者某个时间段,而不关心服务器端文件是否已经更新。

强缓存又分为主要2种:ExpiresCache-Control
Expires: 它保存的是一个绝对时间,既缓存过期时间,它是相对服务器端时间定的,浏览器会判断本地的时间和expores来确定是否要访问本地缓存。这就有个问题,就是服务端的时间和客户端的时间很多时候是不相等的,这就造成不确定性,所以现在几乎很少使用expires。
Cache-control:它保存的是一个相对时间,可以通过设置max-age来确定文件的缓存时间。其原理和expires一样,不过其是相对时间。
如果两者同时存在的,Cache-Control优先级高于Expires。

 

协商缓存

协商缓存就是由服务器来确定缓存资源是否可用,

协商缓存主要分为2种:Last-ModifyETag

Last-Modify:浏览器第一次访问服务器的时候,会在返回的请求头中加上一个Last-Modified字段,其是资源的最后修改时间。当浏览器再次访问服务器时,其请求头中会包含一个If-Modified-Since字段,服务器再判断其是否相同再确定返回304状态码还是200。
ETag:其原理和Last-Modify几乎一样,只不是其返回的是一般是哈希值或对该资源的md5值(生成规则由服务器决定)。其会在请求头携带If-None-Match字段。
如果两者同时存在的,ETag优先级高于Last-Modify
比较;
1.Last-modified只能精确到秒,秒之内的内容更新ETag才能检测
2.文件有时会定时重新生成相同内容,Last-modified不能很好识别
3.ETag每次服务端生成都需要进行读写操作,而last-modified只需要读取操作,etage的消耗更大。

如果有强缓存的话,且强缓存还没过期的情况下,浏览器会优先访问强缓存,并返回200状态码。在没有强缓存或者强缓存过期情况下才会访问协商缓存。再根据etag或last-Modified返回304或200状态码。
在这里插入图片描述
顺便提个问?
当代码上线后,假如我们更新了新的版本,用户怎样才能自行更新而不使用本地的强缓存?
在资源请求的URL中增加一个参数,比如:js/mian.js?ver=0.7.1。这个参数是一个版本号,每一次部署的时候变更一下,当这个参数变化的时候,强缓存都会失效并重新加载。这样一来,静态资源,部署以后就需要重新加载。这样就比较完美的解决了问题。

如果是返回是301或者302的话,网络进程会从响应头的location字段里面读取重定向的地址,再重新发送http或https请求。
 

6.服务器处理请求并返回请求报文,浏览器接受HTTP响应。

浏览器交互过程中涉及的知识点很多,这里主要说下安全问题吧。

网络安全

XSS

概念:跨站脚本攻击,它指的是恶意攻击者往Web页面里面插入恶意代码脚本,而程序员在设计网站中输入输出的部分时,没有对用户输入的内容进行过滤,当用户浏览该页面时,嵌入的Web脚本代码就会被执行,从而达到恶意攻击用户的特殊目的。

防范:
1.设置HttpOnly
xss攻击主要想获取到cookie中的sessionId并劫持会话。当cookie中设置了httponly属性时,那么js脚本将无法读取到cookie信息。
2.输出、输出检查过滤
3.HTML代码转译

CSRF

概念:跨站请求伪造攻击,它通过伪装来自信任用户的请求来攻击受信任的网络,或者理解是盗用用户的身份,以你的名义进行某些非法操作。

防范:
1.验证 HTTP Referer 字段
在HTTP请求头中有一个Refer字段,记录了该HTTP请求的来源地址,只需要核对Refer字段是否是合法来源即可。(IE6可以修改Referer 值)
2.在请求地址中添加token
可以在HTTP请求中以参数加入一个随机的token,并在服务器端建立一个拦截器来验证这个token。
3.在HTTP头中自定义属性并验证
其方法和token差不多,只是将其添加到HTTP头自定义属性中。

SQL注入攻击

概念:攻击者在HTTP请求中注入恶意的SQL代码,服务器使用参数构建数据库SQL命令时,恶意SQL被一起构建,已达成某些非法操作。

防范:
1.有效性检核和过滤。
2.限制字符串输入长度
3.服务器端使用预编译的PrepareStatement。

准备渲染阶段

Chrome会为每个页面分配一个渲染进程,但如果是同一站点(即协议和根域名相同),其会公用同一个渲染进程。官方把这个默认策略叫process-per-site-instance
 

7.构建DOM树,渲染页面

浏览器渲染页面的基本过程:
1.解析HTML文件,创建DOM树
2.解析CSS,形成CSS对象模型
3.将CSS与DOM合并,构建渲染树
4.布局和绘制

构建DOM和CSSOM树

浏览器渲染页面前需要构建DOM和CSSOM树
浏览器解析过程大概经过:字节->字符->令牌->节点->对象模型
在这里插入图片描述
1.转换:浏览器从磁盘或网络读取HTML的原始字节,并根据文件制定的编码将它们转换成各种字符
2.令牌化:浏览器将字符串转换成W3C HTML5标准的规定的各种令牌(节点)
3.词法解析:发出的令牌转换成定义其属性和规则的对象。
4.DOM构建:根据标记之间的关系构建dom。
整个流程的最终输出是这个页面的文档对象模型(DOM),浏览器对页面进行的所有进一步处理都会利用它。

CSSOM树和处理HTML大同小异,处理过程差不多:在这里插入图片描述
CSS字节转化成字符,接着转换成令牌和节点,最后链接成CSS对象模型(CCSOM)

渲染布局和绘制

DOM和CSSOM树构建完成之后,需要合成为渲染树。构建渲染树的工作大概如下:
1.从DOM树的根节点开始遍历每个可见节点。
2.对于每个可见节点,为其找到适配的CSSOM规则并应用。
3.输出可见节点,连同其内容和计算的样式。
有了渲染树下一步是布局,布局做的主要是计算每个节点在页面上的确切位置和大小。
4.接着会创建布局树,并计算节点的布局信息。
5.对布局树进行分成,生成分层树。
6.对每个图层生成绘制命令,并提交给合成线程
7.合成线程将图层分成图块,并进行光栅化处理。
8.光栅化线程池中将图块转换为位图。
10.合成线程发送绘制图块的命令DrawQuad给浏览器进程
11.浏览器进程根据DrawQuad消息生成页面,并显示在显示器上。

此处参考:https://www.cnblogs.com/tootwo2/p/7208890.html
 

8.关闭TCP连接.(四次挥手)

四次挥手

四次挥手过程和三次握手差不多。
第一次挥手:客户端发送一个FIN=1,其序号为seq=u,客户端进入FIN-WAIT-1状态。
第二次挥手:服务器接收到报文后,发送确认报文给客户端ACK=1,ack=u+1,服务端进入CLOSE_WAIT状态。
第三次挥手:服务器发送一个FIN,seq=w,用来关闭客户端与服务器端的数据传送,服务器端进入LAST_ACK状态。
第四次挥手:客户端收到FIN包后,客户端进入TIME_WAIT状态,接着发送一个确认报文ACK给服务器端ack=w+1,服务器接收后,进入CLOSED状态,完成四次握手.
在这里插入图片描述
这里有个2MSL客户端接发送完最后一个ack包后并不会立刻进入CLOSED状态,而会等待2MSL(最长报文段寿命).这是因为:
如果网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值