前端面试八股文
1.HTTP和HTTPS的基本概念
http:是一个客户端和服务端请求和应答的标准(TCP),用于从www服务器传输超文本到本地浏览器的超文本传输协议。
成都创新互联专注为客户提供全方位的互联网综合服务,包含不限于成都网站制作、成都做网站、外贸营销网站建设、扎囊网络推广、微信小程序开发、扎囊网络营销、扎囊企业策划、扎囊品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联为所有大学生创业者提供扎囊建站搭建服务,24小时服务热线:18980820575,官方网址:www.cdcxhl.com
https:是以安全为目标的HTTP通道,即HTTP下加入SSL层进行加密。其作用是:建立一个信息安全通道,确保数据的传输,确保网站的真实性。
补充:SSL是洋文“Secure Sockets Layer”的缩写,中文叫做“安全套接层”。
2.HTTP和HTTPS的区别及优缺点?
- HTTPS 协议需要 CA 证书,费用较高;而HTTP 协议不需要;
- HTTP是超文本传输协议,信息是明文传输;HTTPS协议要比HTTP协议安全,HTTPS是具有安全性的SSL加密传输协议,可防止数据在传输过程中被窃取、改变,确保数据的完整性(当然这种安全性并非绝对的,低于更深的Web安全问题,次数暂且不表);
- HTTP协议的默认端口为80;HTTPS默认端口为443;
- HTTP 协议连接很简单,是无状态的;HTTPS 协议是有SSL 和HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP 更加安全;
3.HTTPS协议工作原理
如何保证信息的安全性:对称加密、非对称加密、数字证书与数字签名
|
一定要用https吗?
https那么的安全,是不是我们在什么场景下都要去使用https进行通信呢?答案是否定的。
1)https虽然提供了消息安全传输的通道,但是每次消息的加解密十分耗时,消息系统资源。所以,除非在一些对安全性比较高的场景下,比如银行系统,购物系统中我们必须要使用https进行通信,其他一些对安全性要求不高的场景,我们其实没必要使用https。
2)使用https需要使用到数字证书,但是一般权威机构颁发的数字证书都是收费的,而且价格也是不菲的,所以对于一些个人网站特别是学生来讲,如果对安全性要求不高,也没必要使用https。
参考:https的工作原理
4.输入url后发生了什么?
- DNS域名解析
- 建立TCP连接(三次握手)
- 发送HTTP请求
- 服务器处理请求,返回响应结果
- 关闭TCP连接(四次挥手)
- 浏览器解析HTML渲染页面,构建DOM树
详解:从输入url到页面加载完成发生了什么?
补充1:为什么url要解析
因为有些字符会引起歧义,如“&”“=”,需要进行转义即编码。比如http:www.baidu.com?key=value,
假如我的key
本身就包括等于=
符号,比如ke=y=value
,就会出现歧义,你不知道=
到底是连接key
和value
的符号,还是说本身key
里面就有=
。
补充2:哪些符号需要编码
RFC3986文档规定,URL 中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~ 4个特殊字符以及所有保留字符( ! * ' ( ) ; : @ & = + $ , / ? # [ ] )。RFC3986文档对 Url 的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。
不安全字符:还有一些字符,当他们直接放在URL中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符,原因有很多。
- 空格:Url 在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉。
- 引号以及<>:引号和尖括号通常用于在普通文本中起到分隔Url的作用
- #:通常用于表示书签或者锚点
- %:百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码
- {}|\^[]`~:某一些网关或者传输代理会篡改这些字符
需要注意的是,对于Url中的合法字符,编码和不编码是等价的,但是对于上面提到的这些字符,如果不经过编码,那么它们有可能会造成Url语义的不同。因此对于Url而言,只有普通英文字符和数字,特殊字符$-_.+!*'()还有保留字符,才能出现在未经编码的Url之中。其他字符均需要经过编码之后才能出现在Url中。
参考:URL原理、URL编码、URL特殊字符
5.TCP三次握手
第一次握手:建立连接,客户端发送SYN包(syn=j)(是TCP/IP建立连接时使用的握手信号。),随后客户端进入SYN-SENT阶段,等待服务端确认。
第二次握手:服务端收到syn包并确认客户的SYN,同时也发送一个自己的SYN包,随后服务器端进入SYN-RCVD阶段。
第三次握手:客户端接收到来自服务器端的确认收到数据的SYN+ACK包,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段,并向服务器发送确认包ACK。随后客户端进入ESTABLISHED阶段。服务器收到来自客户端的“确认收到服务器数据”的TCP报文之后,明确了从服务器到客户端的数据传输是正常的。完成三次握手。
为什么要进行第三次握手?
为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了SYN=1创建连接的请求(第一次握手)。如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。客户端可能设置了一个超时时间,时间到了就关闭了连接创建的请求。再重新发出创建连接的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。
简单来说:得客户端和服务端双方都确定对方能收到请求,如果是两次握手的话,服务端不知道客户端能否收到请求,服务端建立好连接开始发数据,结果发出去的包,客户端一直没收到,那么攻击服务端就很容易,一直发包不接收,服务器很容易就挂掉了。
6.TCP四次挥手
- 首先客户端想要释放连接,向服务器端发送一段TCP报文,随后客户端进入FIN-WAIT-1阶段,即半关闭阶段,并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。
- 服务器端接收到从客户端发出的连接释放报文之后,确认了客户端想要释放连接,发出确认报文,表示“接收到客户端发送的释放连接的请求”。
前"两次挥手"既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了
- 服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,向客户端发出释放报文,等待客户端的确认,随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
- 客户端收到服务器的连接释放报文后,向服务器端发送确认报文,服务器端收到从客户端发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭服务器端到客户端方向上的连接。
简单来说
第一次挥手:客户端告诉服务端我要断开连接了
第二次挥手:服务端告诉客户端我知道你要断开连接了,并告诉客户端你可以断开了
第三次挥手:服务端做好了断开准备,并想客户端发送断开请求,等到客户端确认
第四次挥手:客户端接收到服务端的可以释放的信号,向服务端发送确认断开的信号,服务端收到后就关闭连接。
参考:详解 TCP 连接的“ 三次握手 ”与“ 四次挥手
6.cookie、sessionStorage、localStorage的区别
相同点:都是在开发中用到的临时存储客户端会话信息或者数据的方法
不同点:
1.存储的时间有效期不同
- cookie的有效期是可以设置的,默认的情况下是关闭浏览器后失效
- sessionStorage的有效期是仅保持在当前页面,关闭当前会话页或者浏览器后就会失效
- localStorage的有效期是在不进行手动删除的情况下是一直有效的
2.存储的大小不同
- cookie的存储是4kb左右,存储量较小,一般页面最多存储20条左右信息
- localStorage和sessionStorage的存储容量是5Mb(官方介绍,可能和浏览器有部分差异性)
3.与服务端的通信
- cookie会参与到与服务端的通信中,一般会携带在http请求的头部中,例如一些关键密匙验证等。
- localStorage和sessionStorage是单纯的前端存储,不参与与服务端的通信
参考:cookie、localStorage和sessionStorage三者的区别
7.Vuex 和 localStorage 的区别
- 最重要的区别:vuex 存储在内存中localstorage 则以文件的方式存储在本地,只能存储字符串类型的数据,存储对象需要 JSON 的 stringify 和parse 方法进行处理。读取内存比读取硬盘速度要快。
- 应用场景 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。vuex 用于组件之间的传值。localstorage 是本地存储,是将数据存储到浏览器的方法,一般是在跨页面传递数据时使用 。 Vuex 能做到数据的响应式,localstorage 不能。
- 永久性 刷新页面时 vuex 存储的值会丢失,localstorage 不会。注意:对于不变的数据确实可以用 localstorage 可以代替vuex,但是当两个组件共用一个数据源(对象或数组)时,如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,localstorage无法做到,原因就是区别 1。
8.浏览器如何渲染网页
- 解析HTML生成DOM树- 渲染引擎首先解析HTML文档,生成DOM树
- 构建Render树- 接下来不管是内联式,外联式还是嵌入式引入的CSS样式会被解析生成CSSOM树,根据DOM树与CSSOM树生成另外一棵用于渲染的树-渲染树(Render tree),
- 布局Render树- 然后对渲染树的每个节点进行布局处理,确定其在屏幕上的显示位置
- 绘制Render树- 最后遍历渲染树并用UI后端层将每一个节点绘制出来
解析HTML文件,创建DOM树,自上而下,如果遇到样式(link、style)与脚本(script)都会阻塞
补充1:避免JavaScript阻塞JavaScript 脚本延迟加载的方式有哪些?
- defer 属性:给 js 脚本添加 defer 属性,这个属性会让脚本的加载与文档的解析同步解析,然后在文档解析完成后再执行这个脚本文件,这样的话就能使页面的渲染不被阻塞。多个设置了defer属性 14 的脚本按规范来说最后是顺序执行的,但是在一些浏览器中可能不是这样。
- async 属性:给 js 脚本添加 async 属性,这个属性会使脚本异步加载,不会阻塞页面的解析过程,但是当脚本加载完成后立即执行js脚本,这个时候如果文档没有解析完成的话同样会阻塞。多个async属性的脚本的执行顺序是不可预测的,一般不会按照代码的顺序依次执行。
- 动态创建 DOM 方式:动态创建 DOM 标签的方式,可以对文档的加载事件进行监听,当文档加载完成后再动态的创建script 标签来引入js 脚本。
- 使用 setTimeout 延迟方法:设置一个定时器来延迟加载js 脚本文件
- 让 JS 最后加载:将 js 脚本放在文档的底部,来使js 脚本尽可能的在最后来加载执行。
补充2:页面渲染优化
- HTML文档结构层次尽量少,最好不深于六层;
- 脚本尽量后放,放在前即可;
- 少量首屏样式内联放在标签内;
- 样式结构层次尽量简单;
- 在脚本中尽量减少DOM操作,尽量缓存访问DOM的样式信息,避免过度触发回流;
- 减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;
- 动画尽量使用在绝对定位或固定定位的元素上;
- 隐藏在屏幕外,或在页面滚动时,尽量停止动画;
- 尽量缓存DOM查找,查找器尽量简洁;
- 涉及多域名的网站,可以开启域名预解析
9.重绘与重排相关
重绘与重排的区别
重排:当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档的过程就称为重排/回流。
重绘:当页面中某些元素的样式发生变化,但是不会影响其在文档流中的位置时,浏览器就会对元素进行重新绘制,这个过程就是重绘。
如何触发重绘与重排
下面这些操作会导致重排/回流:
页面的首次渲染 、浏览器的窗口大小发生变化 、元素的内容发生变化 、元素的尺寸或者位置发生变化、 元素的字体大小发生变化、 激活 CSS 伪类、 查询某些属性或者调用某些方法 、添加或者删除可见的 DOM 元素
在触发回流(重排)的时候,由于浏览器渲染页面是基于流式布局的,所以当触发回流时,会导致周围的 DOM 元素重新排列,它的影响范围有两种: 全局范围:从根节点开始,对整个渲染树进行重新布局局部范围:对渲染树的某部分或者一个渲染对象进行重新布局
下面这些操作会导致重绘:
color、background 相关属性:background-color、background-image等 outline 相 关 属 性 : outline-color 、outline-width、text-decoration border-radius、visibility、box-shadow 注意: 当触发重排/回流时,一定会触发重绘,但是重绘不一定会引发重排/回流。
如何避免重绘或重排
- 用transform做形变和位移可以减少reflow
- 避免逐个修改节点样式,尽量一次性修改
- 使用DocumentFragment将需要多次修改的DOM元素缓存,最后一次性append到真实DOM中渲染
- 可以将需要多次修改的DOM元素设置display:none,操作完再显示。(因为隐藏元素不在render树内,因此修改隐藏元素不会触发回流重绘)
- 避免多次读取某些属性
- 通过绝对位移将复杂的节点元素脱离文档流,形成新的Render Layer,降低回流成本
- 提升为合成层 将元素提升为合成层有以下优点:
- 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
- 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
- 对于 transform 和 opacity 效果,不会触发 layout 和 paint
提升合成层的最好方式是使用 CSS 的 will-change 属性:
#target{ will-change: transform; }
分享文章:前端面试八股文
链接URL:http://hbruida.cn/article/dsojgci.html