传送门>>>
上一篇:
Day3 - 前端高频面试题之基础版
1、什么是options预请求?
options预请求是浏览器自主发起的,分别根据预检请求报文中的 Access-Control-Request-Method
、Access-Control-Request-Headers
来判断该请求是否是服务器允许的提交方式和允许的请求头字段;
服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。
2、解释一下事件冒泡和事件捕获呢?如何阻止冒泡?如何阻止默认事件?手写一个事件委托的例子呢?
一个完整的JS事件流是从window开始,最后回到window的一个过程;
事件流被分为三个阶段(1 ~ 5)捕获过程、(5 ~ 6)目标过程、(6 ~ 10)冒泡过程。
事件冒泡就是事件从最深的节点开始,然后逐步向上传播事件的过程;
事件捕获就是从window开始,逐步向最深的节点传播事件的过程
// 事件委托:就是把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理
var ul = document.getElementByTagName('ul)[0]
ul.onclick = function(e) {
e = e || window.event
alert(e.target.innerHtml)
}
// 阻止冒泡: window.event? window.event.cancelBubble = true(IE) : e.stopPropagation()
// 阻止默认事件: e.preventDefault() || window.event.returnValue = false(IE)
3、请描述一下内存泄漏的原因和场景?那js的垃圾回收机制有哪些?
内存泄漏指的是浏览器不能正常的回收内存的现象
- 全局变量引起的内存泄漏
- 闭包引起的内存泄漏
- dom清空或删除时,事件未清除导致的内存泄漏
当函数执行结束,局部变量就不需要了,这时候就可以释放他们的内存。
两种回收机制:
- 引用计数法
跟踪记录每个值被引用的次数。当声明一个变量并将引用类型的值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次 数加1.相反,如果包含对这个值引用的变量又取得另外一个值,则这个值的引用次数减1.当这个值的引用次数变成0时,则说明没有办法访问这个值了,因此就 可以将其占用的内存空间回收回来
- 标记清除法
标记清除的算法分为两个阶段,标记(mark)和清除(sweep)
第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。
4、DOM事件中target和currentTarget的区别
- event.target 返回触发事件的元素
- event.currentTarget 返回绑定事件的元素
5、跨域的几种方式?
- (利用script标签的跨域能力)跨域
- websocket(html5的新特性,是一种新协议)跨域
- 设置代理服务器(由服务器替我们向不同源的服务器请求数据)
- CORS(跨源资源共享,cross origin resource sharing)
- iframe跨域
- postMessage(包含iframe的页面向iframe传递消息)
6、说一下浏览器的缓存机制呢
浏览器缓存机制有两种,一种为强缓存,一种为协商缓存。
对于强缓存,浏览器在第一次请求的时候,会直接下载资源,然后缓存在本地,第二次请求的时候,直接使用缓存。
对于协商缓存,第一次请求缓存且保存缓存标识与时间,重复请求向服务器发送缓存标识和最后缓存时间,服务端进行校验,如果失效则使用缓存。
- 强缓存方案
Exprires:服务端的响应头,第一次请求的时候,告诉客户端,该资源什么时候会过期。Exprires的缺陷是必须保证服务端时间和客户端时间严格同步。
Cache-control:max-age,表示该资源多少时间后过期,解决了客户端和服务端时间必须同步的问题,
- 协商缓存方案
If-None-Match/ETag:缓存标识,对比缓存时使用它来标识一个缓存,第一次请求的时候,服务端会返回该标识给客户端,客户端在第二次请求的时候会带上该标识与服务端进行对比并返回If-None-Match标识是否表示匹配。
Last-modified/If-Modified-Since:第一次请求的时候服务端返回Last-modified表明请求的资源上次的修改时间,第二次请求的时候客户端带上请求头If-Modified-Since,表示资源上次的修改时间,服务端拿到这两个字段进行对比。
7、请详细描述一下从输入URL到页面加载的全过程
主干流程:浏览器构建HTTP Request请求、网络传输、服务器构建HTTP Response请求、网络传输、浏览器渲染页面。
一、构建请求
-
应用层进行DNS解析
- 这里使用DNS预解析,可以根据浏览器定义的规则,提前解析之后可能会用到的域名,使解析结果缓存到
系统缓存
中,缩短DNS解析时间,来提高网站的访问速度
- 这里使用DNS预解析,可以根据浏览器定义的规则,提前解析之后可能会用到的域名,使解析结果缓存到
-
应用层生成http请求报文
- HTTP请求报文包括起始行、首部和主体部分
- 起始行可能:
GET https://baidu.com/ HTTP/1.1
- 首部包括:
HOST keep-alive Accpet-Encoding Accept-Language User-Agent Cookie
等 - 首部和主体内容之间有一个回车换行(CRLF),主体内容即要传输的内容。如果是get请求,则主体内容为空
-
传输层建立TCP连接 (建立三次握手)
传输协议主要有UDP(无连接的协议、不可靠)和TCP(有连接、可靠)两种
TCP可靠主要表现在:
- 接收方会对接收到的数据进行确认
- 发送方会重传接收方未确认的数据
- 接收方会对接收到的数据按照正确的顺序进行重新排列,并删除重复的数据
- 提供了控制拥挤的机制
-
三次握手:
- 第一次握手:主机A发往主机B,主机A初始序号是X,设置SYN(同步)位,未设置ACK(确认)位
- 第二次握手:主机B发往主机A,主机B初始序号是Y,ACK(确认号)是X+1,X+1暗示已经收到主机A发来主机B的同步序号。设置ACK位和SYN位
- 第三次握手:主机A发往主机B,主机A初始序号是X+1,ACK是Y+1,Y+1暗示已经收到主机A发来主机B的同步序号。设置ACK位,未设置SYN位。
三次握手解决的不仅仅有序号问题,还解决了包括窗口大小、MTU(Maximum Transmission Unit,最大传输单元),以及所期望的网络延时等其他问题。
-
构建TCP请求会增加大量的网络时延,常用的优化方式如下所示
- 资源打包,合并请求
- 多使用缓存,减少网络传输
- 使用keep-alive建立持久连接
- 使用多个域名,增加浏览器的资源并发加载数,或者使用HTTP2的管道化连接的多路复用技术
-
网络层使用IP协议来选择路线
-
数据链路层实现网络相邻节点间的可靠的数据通信
-
物理层传输数据
二、网络传输
从客户机到服务器需要通过许多网络设备, 一般地,包括集线器、交换器、路由器等
三、服务器处理及反向传输
四、浏览器渲染
- 首先浏览器从服务器接收到html代码,然后开始解析html
- 根据html代码自顶向下构建DOM树,并且同时构建渲染树
- 遇到js文件加载执行,将阻塞DOM树的构建
- 遇到css文件,将阻塞渲染树的构建
- script标签中的defer属性:构建DOM树的过程和js文件的加载异步(并行)进行,但是js文件执行需要在DOM树构建完成之后
- script标签中的async属性:构建DOM树、渲染树的过程和js文件的加载和执行异步(并行)进行
- 所以script标签最好放在标签的前面,因为放在所有body中的标签后面就不会出现网页加载时出现空白的情况,可以持续的给用户提供视觉反馈,同时在有些情况下,会降低错误的发生。
- 而css标签应该放在标签之间,因为如果放在标签的前面,那么当DOM树构建完成了,渲染树才构建,那么当渲染树构建完成,浏览器不得不再重新渲染整个页面,这样造成了资源的浪费。效率也不高。如果放在之间,浏览器边构建边渲染,效率要高的多。总的来说,就是提高性能,提高网页的可读性。
五、重绘和回流
- 页面生成以后,脚本操作、样式表变更,以及用户操作都可能触发重绘和回流
- 回流是指窗口尺寸被修改、发生滚动操作,或者元素位置相关属性被更新时会触发布局过程,也就是重新进行流式布局的过程。发生在Render树上,常说的脱离文档流,就是指脱离渲染树Render Tree
- 重绘是指当与视觉相关的样式属性值被更新时会触发绘制过程,在绘制过程中要重新计算元素的视觉信息,使元素呈现新的外观。是发生在渲染层 render layer上
- 减少回流次数的方法
- 不要一条一条地修改DOM样式,而是修改className或者修改style.cssText
- 在内存中多次操作节点,完成后再添加到文档中去
- 对于一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示
- 在需要经常获取那些引起浏览器回流的属性值时,要缓存到变量中
- 不要使用table布局,因为一个小改动可能会造成整个table重新布局。而且table渲染通常要3倍于同等元素时间
- 减少重绘范围的方法
- 将需要多次重绘的元素独立为render layer渲染层,如设置absolute,可以减少重绘范围
- 对于一些进行动画的元素,可以进行硬件渲染,从而避免重绘和回流
8、http状态码
http状态码是表示服务器对请求的响应状态,
主要分为以下几个部分
- 1**:这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束
- 2**:表示请求成功
- 3**:表示重定向
- 4**:表示客户端错误
- 5**:表示服务器端错误
- 100(continue),客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收
- 200(OK),表示请求成功,请求所希望的响应头或数据体将随此响应返回。
- 202(Accepted),服务器已接受请求,但尚未处理。
- 204(No-Content),服务器成功处理了请求,但不需要返回任何实体内容
- 205(Reset-Content),服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。
- 206(Partial-Content),服务器已经成功处理了部分 GET 请求。
- 301(Moved-Permanently),永久性重定向
- 302(Moved-Temporarily),暂时性重定向
- 304(Not-Modified),浏览器端缓存的资源依然有效
- 400(Bad-Reques),请求有误,当前请求无法被服务器理解。
- 401(Unauthorized),当前请求需要用户验证。
- 403(Forbidden),服务器已经理解请求,但是拒绝执行它。
- 404(Not-Found),请求的资源没有被找到
- 500(Interval Server Error),服务器内部错误
- 502(Bad GateWay),网关出错
- 503(Service Unavailable),由于临时的服务器维护或者过载,服务器当前无法处理请求。
- 504(Gateway Timeout),作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。