注册

学前端必读的从输入url到页面渲染全过程

从输入 URL 到页面展示这中间到底发生了什么?,这是一道非常经典的面试题,这一过程涉及到了计算机网络、操作系统、Web等一系列知识,如果对这一过程有非常好的了解,对以后的开发甚至是程序的优化都是非常有益的。现将过程梳理如下:


1. 解析URL


分析所需要使用的传输协议和请求的资源路径。如果url中的协议或主机名不合法,将会把地址栏中输入的内容传递给搜索引擎,如果没有问题,浏览器会检查url中是否出现了非法字符,如果存在,对非法字符(空格、汉字等双字节字符)进行转义后在进行下一过程。


编码和解码:



  • encodeURI()/decodeURI():encodeURI()函数只会把参数中的空格编码为%20,汉字进行编码,其余特殊字符不会转换
  • encodeURIComponent()/decodeURIComponent():由于这个方法对:/都进行了编码,所以不能用它来对网址进行编码,适合对URL中的参数进行编码
  • escape()/unescape():将字符的unicode编码转化为16进制序列,不对ASCII字母和数字进行编码,也不会对' * @ - _ + . / '这些ASCII符号进行编码,用于服务器与服务器端传输多
let url = "http://www.baidu.com/test /中国"
console.log(encodeURI(url)); // http://www.baidu.com/test%20/%E4%B8%AD%E5%9B%BD
let url1 = `https://www.baidu.com/from=${encodeURIComponent('http://wwws.udiab.com')}`
console.log(url1); // https://www.baidu.com/from=http%3A%2F%2Fwwws.udiab.com
console.log(escape(url)); // http%3A//www.baidu.com/test%20/%u4E2D%u56FD

1.1 URL地址格式


传统格式:scheme://host:port/path?query#fragment。例:http://www.urltest.cn/system/user…



  • scheme(必写):协议http(超文本传输协议)、https(安全超文本传输协议)、ftp(文件传输协议,用于将文件下载或上传至网站)、file(计算机上的文件)
  • host(必写):域名或IP地址
  • port(可省略):端口号,http默认80,https默认443
  • path:路径,例如 /system/user
  • query:参数,例如 username=falcon&age=18
  • fragment:锚点(哈希hash),用于定位页面的某个位置

Restful格式:可以通过不同的请求方式(get、post、put、delete)来实现不同的效果



2. 缓存判断


浏览器缓存就是浏览器将用户请求过的资源存储到本地电脑。当浏览器再次访问时就可以直接从本地加载,不需要去服务器请求,能有效减少不必要的数据传输,减轻服务器负担,提升网站性能,提高客户端网页打开速度。浏览器缓存一般分为强缓存和协商缓存


image.png



  • 浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control、expires信息),命中则直接从缓存中获取资源信息,不会向服务器发起请求;
  • 如果没有命中强缓存,浏览器会发送请求(携带该资源缓存的第一次请求返回的header字段信息,Last-Modified/If-Modified-Since、Etag/If-None-Match)到服务器,由服务器根据请求中携带的相关header字段进行对比来判断是否命中协商缓存,命中则返回新的header信息更新缓存中对应的header信息,不返回资源内容,浏览器直接从缓存中获取;否则返回最新的资源内容

2.1 强缓存



  • expires,绝对时间字符串,发送请求在这个时间之前有效,之后无效

catch-control,几个比较常用的字段如下:



  • max-age=number,相对字段,利用资源第一次请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,然后再进行比较
  • no-cache,不使用本地缓存,需要使用协商缓存
  • no-store,禁止浏览器缓存数据,每次用户都需要向服务器发送请求获取完整资源
  • public,可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器
  • private,只能被终端用户浏览器缓存

【注】



  • 强缓存如何重新加载缓存过的资源?使用强缓存,不用向服务器发送请求就可以获取到资源,如果在强缓存期间,资源发生了变化,浏览器就一直得不到最新的资源,如何操作:通过更新页面中引用的资源路径,让浏览器主动放弃缓存,加载新的资源
  • 如果二者同时存在,cache-control的优先级高于expires

2.2 协商缓存


Last-Modified/If-Modified-Since



  • 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,会在response的header上加上Last-Modified(表示资源在服务器上的最后修改时间)字段
  • 浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since(值就是上一次请求返回的Last-Modified值)字段,来判断是否发生变化,没变化返回304,从缓存中加载,也不会重新在response的header上添加Last-Modified;发生变化则直接从服务器加载,并且更新Last-Modified值

Etag/If-None-Match



  • 这两个值是由服务器生成的每个资源的唯一标识字符串,只要资源变化值就会发生改变
  • 判断过程与上面一组逻辑类似
  • 不同的是,当服务器返回304时,由于Etag重新生成过,response的header还是会把这个Etag返回

【注】



  • 为什么需要Etag?一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变修改时间);某些文件修改非常频繁(例如在秒以下的时间进行修改);某些服务器不能精确得到文件的最后修改时间等这些情况下,利用Etag能够更加精确的控制缓存
  • 两者可以一起使用,服务器会优先验证Etag,在一致的情况下,才会继续比对Last-Modified

2.3 用户行为对缓存的影响


image.png


3. DNS解析


获取输入url中的域名对应的IP地址。



  • 第一步,检查浏览器缓存中是否缓存过该域名对应的IP地址;
  • 第二步,检查本地的hosts文件(系统缓存)
  • 第三步,本地域名解析服务器进行解析;
  • 第四步,根域名解析服务器进行解析;
  • 第五步,gTLD服务器进行解析(顶级域名)
  • 第六步,权威域名服务器进行解析,最终获得域名IP地址;

3.1 域名层级结构图


image.png



  • 根域:位于域名空间最顶层,一般用一个点“.”表示
  • 顶级域:一般表示一种类型的组织机构或者国家地区。.net(网络供应商) .com(工商企业) .org(团体组织) .edu(教育机构) .gov(政府部门) .cn(中国国家域名)
  • 二级域:用来标明顶级域内一个特定的组织。.com.cn .net.cn .edu.cn
  • 子域:二级域下所创建的各级域名,各个组织或用户可以自由申请注册
  • 主机:位于域名空间最下层,一台具体的计算机。完整格式域:http://www.sina.com.cn

3.2 递归查询、迭代查询


用户向本地DNS服务器发起请求属于递归请求;本地DNS服务器向各级域名服务器发起请求属于迭代请求
image.png



  • 递归查询:以本地DNS服务器为中心,客户端发出请求报文后就一直处于等待状态,直到本地DNS服务器发来最终查询结果
  • 迭代查询:DNS服务器如有客户端请求数据则返回正确地址;没有则返回一个指针;按指针继续查询

4. TCP三次握手建立连接


image.png



  • 第一步,客户端发送SYN包(seq=x)到服务器,等待服务器确认
  • 第二步,服务器收到SYN包,确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包
  • 第三步,客户端收到SYN+ACK包,向服务器发送确认包ACK(ack=y+1)

三次握手完成,客户端和服务器正式开始传递数据


4.1 TCP、UDP



  • TCP 面向连接的协议,只有建立后才可以传递数据
  • UDP 无连接的协议,可以直接传送数据,传输效率较高,但不能保证数据的完整性

5. 发起http、https请求


5.1 http1.0、http1.1、http2.0区别



5.2 http、https



  • https需要CA申请证书,一般需要交费
  • http运行在TCP之上,明文传输;https运行在SSL/TLS之上,SSL/TLS运行在TCP之上,加密传输
  • http默认端口80,https默认端口443
  • https可以有效的防止运营商劫持

5.3 XSS、CSRF


XSS


XSS(Cross-site Scripting)。跨域脚本攻击,指通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序等。


分类如下:


image.png



  • 反射型。发出请求时,xss代码出现在URL中,作为输入提交到服务器端,服务器端解析后响应,xss代码随响应内容一起传回浏览器,最后浏览器解析执行xss代码。例如:"http://www.a.com/xss/reflect…"
    image.png
  • 存储型。和反射型的差别是提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求目标页面时不用再提交XSS代码。例如:留言板xss,用户提交留言到数据库,目标用户查看留言板时,留言的内容会从数据库查询出来并显示,浏览器解析执行,触发xss攻击
  • DOM型。不需要服务器的参与,触发xss靠的是浏览器端的DOM解析,完全是客户端触发

防御措施:



  • 过滤。对用户的输入(和URL参数)进行过滤。移除用户输入的和事件相关的属性,如onerror、onclick等;移除用户输入的Style节点、Script节点(一定要特别注意,它是支持跨域的)、Iframe节点
  • 编码。对输出进行html编码。对动态输出到页面的内容进行html编码,使脚本无法再浏览器中执行
  • 服务端设置会话Cookie的HTTP Only属性,这样客户端的JS脚本就不能获取cookie信息了

CSRF


CSRF(Cross-site request forgery)。跨站请求伪造,攻击者通过伪造用户的浏览器请求,向用户曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于转账、盗号、发送虚假消息等
image.png


防御措施:



  • token验证。服务器返回给客户端一个token信息,客户端带着token发送请求,如果token不合法,服务器拒绝这个请求
  • 隐藏令牌。将token隐藏在http的header中
  • referer验证。页面请求来源验证,只接受本站的请求,其他进行拦截

5.4 get、post


GET



  • 一般用于获取数据;
  • 参数放在url中;
  • 浏览器回退或刷新无影响;
  • 请求可被缓存;
  • 请求的参数放url上,有长度限制;
  • 请求的参数只能是ASCII码;
  • url对所有人可见,安全性差;
  • get产生一个tcp数据包,hearder、data一起发送一次请求,服务器返回200

POST



  • 一般用于向后台传递数据、创建数据;
  • 参数放在body里;
  • 浏览器回退或刷新数据会被需重提交;
  • 请求不会被缓存;
  • 请求的参数放body上,无长度限制;
  • 请求的参数类型无限制,允许二进制数据;
  • 请求参数不会被保存在浏览器历史或web服务器日志中,相对更安全;
  • post产生两个tcp数据包,先发送header,返回100 continue,再发送data,服务器返回200,但不是绝对的,Firefox只发送一次

5.5 状态码


1XX - 通知



  • 100 -- 客户端继续发送请求
  • 101 -- 切换协议

2XX - 成功



  • 200 -- 请求成功,一般应用与 get 或 post 请求
  • 201 -- 请求成功并创建新的资源,

3XX - 重定向



  • 301 -- 永久移动,请求的资源已被永久移动到新的 url,返回信息包括新的 url,浏览器会自动定向到新的 url,今后所有的请求都是新的 url
  • 302 -- 临时移动,资源只是临时移动,客户端应继续使用旧的 url
  • 304 -- 所请求的资源未修改,不会返回任何资源。浏览器请求的时候,会先访问强缓存,没有则访问协商缓存,协商缓存命中,资源未修改,返回 304

4XX - 客户端错误



  • 400 -- 客户端请求的语法错误,服务器无法理解(z 字段类型,或对应的值类型不一致;或者没有进行 JSON.toStringfy 的转换)
  • 401 -- 请求需要用户的认证
  • 403 -- 服务器理解客户端请求,但是拒绝执行
  • 404 -- 服务器无法根据客户端的请求找到资源

5XX - 服务器端错误



  • 500 -- 服务器内部错误,无法完成资源的请求
  • 501 -- 服务器不支持请求功能,无法完成资源请求
  • 502 -- 网关或代理服务器向远程服务器发送请求返回无效

5.6 跨域



  • 跨域:浏览器不能执行其他网站的脚本,这是由于同源策略(同协议、同域名、同端口)限制造成的
  • 同源策略限制的行为:cookie,localstorage和IndexDB无法读取;DOM无法获取;Ajax请求不能发送

跨域的几种解决方式:



  • jsonp,实现原理是<script>标签的src可以发跨域请求,不受同源策略限制,缺点是只能实现get一种请求
  • document.domain + iframe跨域domain属性可返回下载当前文档的服务器域名,此方案仅限主域相同,子域不同的跨域场景
  • 跨域资源共享(CORS)只服务端设置Access-Control-Allow-Origin即可,前端无需设置;若要带cookie请求,前后端都需要设置
  • nginx反向代理跨域,项目中常用的一种方案
  • html5的postMessage(跨文档消息传输),WebSocket(全双工通信、实时通信)

6. 返回数据


当页面请求发送到服务器端后,服务器端会返回一个html文件作为响应


7. 页面渲染


7.1 加载过程



  • HTML会被渲染成DOM树。HTML是最先通过网址请求过来的,请求过来之后,HTML本身会由一个字节流转化成一个字符流,浏览器端拿到字符流,之后通过词法分析,将相应的词法分析成相应的token,转化不同的token tag,然后通过token类型append到DOM树
  • 遇到link token tag,去请求css,然后对css进行解析,生成CSSOM树
  • DOM树和CSSOM树结合形成Render Tree,再进行布局和渲染
  • 遇到script tag,然后去请求JS相关的web资源,请求回来的js交给浏览器的v8引擎进行解析
    image.png

7.2 加载特点



  • html文档解析,对tag依次从上到下解析,顺序执行
  • html中可能会引入很多css,js的web资源,这些资源在浏览器中是并发加载的。
  • DOM树和CSSOM树通常是并行构建的, 所以CSS加载不会阻塞DOM的解析;Render树依赖DOM树和CSSOM树进行,所以CSS加载会阻塞DOM的渲染css会阻塞js文件执行,但不会阻塞js文件下载,因为GUI渲染线程与JavaScript线程互斥,JS有可能影响样式;js会阻塞DOM的解析(把js文件放在最下面),也就会阻塞DOM的渲染,同时js顺序执行,也会阻塞后续js逻辑的执行
  • 依赖关系。页面渲染依赖于css的加载;js的执行顺序依赖关系;js逻辑对于dom节点的依赖关系,有些js需要去获取dom节点
  • 引入方式。直接引入,不会阻塞页面渲染;defer不会阻塞页面渲染,顺序执行;async不会阻塞页面渲染,先到先执行,不保证顺序;异步动态js,需要的时候引入

【注】css样式置顶;js脚本置底;用link代替import;合理使用js异步加载


资源加载完成后,通过样式计算、布局设置、分层、绘制等过程,将页面呈现出来


7.3 重绘回流


根据渲染树,浏览器可以计算出网页中有哪些节点,各节点的CSS以及从属关系,发生回流;根据渲染树以及回流得到的节点信息,计算出每个节点在屏幕中的位置,发生重绘



  • 元素的规模尺寸、布局、显隐性发生变化时,发生回流,每个页面至少产生一次回流,第一次加载
  • 元素的外观、风格、颜色等发生变化而不影响布局,发生重绘
  • 回流一定发生重绘,重绘不一定发生回流

【避免措施】


样式设置



  • 避免使用层级较深的选择器
  • 避免使用 css 表达式
  • 元素适当的定义高度或最小高度
  • 给图片设置尺寸
  • 不要使用 table 布局
  • 能 css 实现的,尽量不要使用 js 实现

渲染层



  • 将需要多次重绘的元素独立为 render layer,如设置 absolute,可以减少重绘范围
  • 对于一些动画元素,使用硬件渲染

DOM 优化



  • 缓存 DOM
  • 减少 DOM 深度及 DOM 数量
  • 批量操作 DOM
  • 批量操作 CSS 样式
  • 在内存中操作 DOM
  • DOM 元素离线更新
  • DOM 读写分离
  • 事件代理
  • 防抖和节流
  • 及时清理环境

TCP四次挥手断开连接


image.png



  • 客户端发送一个FIN(seq=u)数据包到服务器,用来关闭客户端到服务器的数据连接
  • 服务器接受FIN数据包,发送ACK(seq=u+1)数据包到客户端
  • 服务器关闭与客户端的连接并发送一个FIN(seq=w)数据包到客户端,请求关闭连接
  • 客户端发送ACK(seq=w+1)数据包到服务器,服务器在收到ACK数据包后进行CLOSE状态,客户端在一定时间没有收到服务器的回复证明其关闭后,也进入关闭状态

作者:可乐冰冰冰
链接:https://juejin.cn/post/7252869090549268538
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册