《前端面试百问》
浏览器中从输入网址到跳转显示页面经历了哪些事
首先,第一步肯定是 DNS 解析
DNS 解析:将域名解析成 IP 地址
- 读取浏览器 DNS 缓存:有缓存的话就会进行读取,没有的话就从系统也就是计算机的缓存去读取;
- 读取系统 DNS 缓存:有的话就读取,没有就会去路由去缓存中读取(前提是有路由器缓存,如果还没有就会去读取网络运行商的缓存)
- 读取路由器 DNS 缓存:
- 网络运营商的 DNS 缓存
如果上述都没有找到的话,他会去做递归搜索,如果还没有就是找不到对应的 Ip 地址,就会出错TCP 连接(和服务器建立连接)
第一次握手:浏览器发起,用来告诉服务器客户端将要发送请求;
第二次握手:服务器收到客户端想要连接的信号,验证后向客户端发送请求;
第三次握手:客户端接收到服务器发送的请求,确认后想服务器发送请求;
注:三次握手的原因是服务器在运行过程中回去处理很多很多的请求,如果是立马连接的话,可能会连接不上,为了保证通信,所以就有了服务器先确认是否能进行连接;
发送请求:
- 请求报文:HTTP 协议的通信内容
接受响应:
- 响应报文
浏览器接受到服务器发送的数据来进行渲染页面:
- 遇见 html 标记,浏览器会调用 HTML 解析器解析成 Token 并构建 DOM 树
- 遇见 style 标记,浏览器会调用 CSS 解析器来处理 css 标记并创建 CSSDOM 树
- 遇见 Script 标记,浏览器会调用 javascript 解析器来处理 js 代码(绑定事件,修改 DOM 树,CSSDOM 树)
- 将 DOM 树和 CSSDOM 树合成一个渲染树;
- 根据渲染来计算布局,计算每一个节点的几何信息(布局);
- 将各个节点的颜色绘制到屏幕上(渲染);
注:这几步不一定按顺序执行,如果 DOM 树或者 CSSDOM 树被修改了,可能会执行多次布局和渲染,往往实际页面中,这些步骤会被执行多次;
断开连接(TCP 的四次挥手)
- 第一次挥手:由浏览器发起的,告诉服务器所要(请求报文)已经接受完了,你准备关闭吧;
- 第二次挥手:服务器发起告诉浏览器请求报文已经接收完了,并告诉浏览器他准备关闭了,你准备吧;
- 第三次挥手:服务器发送请求告诉浏览器他内容(响应报文)发送完了,准备关闭,让浏览器准备断开连接
- 第四次挥手:告诉服务器内容接受完了,我准备关闭(响应报文),你服务器也准备关闭吧
注:一般是服务器先关然后浏览器关闭
页面之间的传参有哪几种
- H5 的数据存储 localStorage 和 sessionStorage;
- 通过 url 来传参,参数拼接在地址栏,通过 window.location.search()来获取参数;
- 通过 cookie 也是可以的,但由于他支持的 api 较少,所以很少用他;
(主要是每次请求都要带上 cookie 的信息,增加了流量的消耗;另外,cookie 使用的是明文传输,如果被人拦截了就会获取到 session 的所有信息,有一定的安全隐患;还有就是 cookie 数量和长度的限制,每个 domain 最多只能有 20 条 cookie,每个 cookie 的长度不能超过 4K,否则会被截掉)
浏览器缓存和离线缓存有什么区别
离线缓存是 H5 提供使用的功能,让应用程序可以获取本地的网站内容,提高网站的性能,增加用户体验,这个是要我们手动去操作的;(离线缓存是通过 manifast 文件来管理的,需要服务器端的支持,不同的服务器端的开启方式是不同的)
浏览器缓存:浏览器的缓存他会对相同的内容进行缓存,以提高访问的速度,这是浏览器自身的机制所导致的;
他们之间的区别
离线缓存为整个 web 提供服务,浏览器只是缓存单个页面;
离线缓存可以指定需要缓存的文件和需要在线浏览的文件,浏览器是没法指定的;
离线缓存可以动态通知用户进行更新;
对 this 的理解
this
是 js 中的关键字,只存在于函数的内部,严格模式下 this 指向是 undefined
原则上是谁调用就指向谁,只有调用才有 this,所以 this 的指向有四种情况:
- 函数调用模式
this 指向 widow;
- 方法调用模式
谁调用就指向谁
- 构造函数调用模式
this 指向实例;
- 格式上下文
- call 的后面传入的参数时字符串形式参数;
- apply 是以数组方式传入;
- bind 返回新的函数,并绑定死 this 指向;
iframe 的优缺点
iframe 作为嵌入式框架,嵌入式框架和框架网页类似,他可以把一个网页的框架和内容嵌入现有的网页里;
- iframe 的优点
- 能够原封不动的将嵌入的网页展示出来;
- 如果有多个网页引用 iframe,那么只需要修改 iframe 的内容就可以实现调用每一个网页内容进行更改,方便快捷;
- 网页如果统一风格,头部和版本都是一样的,就可以写成一个网页,用 iframe 来嵌套,可以增加代码的复用率;
- 如果遇到加载缓慢的第三方的内容比如说图标活着广告,这些问题都可以用 iframe 来解决;
- 重载页面的时候不需要加载整个页面,只需要重载页面的一个框架,从而减少了一些数据的传输,提升了页面的加载速度,从而提升了用户体验;
- iframe 的缺点
- 页面的样式调试比较麻烦,可能会出现多个滚动条;
- 浏览器的后退按钮会失效;
- 过多和增加服务器的 http 请求;
- 小型的移动设备无法完全显示框架;
- 会产生多个页面,不易管理;
- 不容易打印;
- 代码复杂,无法被一些搜索引擎解读,不利于 SEO;
async 和 promise 的区别
- async 是函数前的一个关键字,await 关键字只能使用在 async 定义的函数中,任何一个 async 函数会隐式返回一个 promise,并且 promise resolve 的值是 return 的返回值;
2。 promise 的写法比回调函数的写法大大改进,但是一眼看上去代码全是 promise API ,什么.then .catch 啥的,操作本身的语义更不容易看出来; - async 配合 promise 语法让 promise 从异步变成了同步,await 后的代码必须执行完了才会进行下一步操作