面试题

[toc]

备注:大部分从面试题从晒兜斯收录

HTML

页面导入样式时,使用 link 和 @import 有什么区别?

  • 从属关系区别。@import 只能导入样式表,link 还可以定义 RSS、rel 连接属性、引入网站图标等;
  • 加载顺序区别;加载页面时,link 标签引入的 CSS 被同时加载;@import 引入的 CSS 将在页面加载完毕后被加载;
  • 兼容性区别;

常见浏览器内核有哪些?

内核

  • Trident:IE 浏览器内核;
  • Gecko:Firefox 浏览器内核;
  • Presto:Opera 浏览器内核;
  • Webkit:Safari 浏览器内核;
  • Blink:谷歌浏览器内核,属于 Webkit 的一个分支,与 Opera 一起在研发;

浏览器

  • IE:Trident,IE 内核;
  • Chrome:以前是 Webkit,现在是 Blink 内核;
  • Firefox:Gecko 内核;
  • Safari:Webkit 内核;
  • Opera:一起是 Presto,现在是 Blink 内核;
  • 360、猎豹浏览器内核:IE + Blink 双内核;
  • 搜狗、遨游、QQ 浏览器内核:Trident(兼容模式)+ Webkit(高速模式);
  • 百度浏览器内核:IE 内核;
  • 2345 浏览器:以前是 IE 内核,现在是 IE + Blink 双内核;
  • UC 浏览器内核:Webkit + Trident;

简述浏览器的渲染原理是什么?

  1. 首先解析收到的文档,根据文档定义构建一颗 DOM 树,DOM 树是由 DOM 元素及属性节点组成的;
  2. 然后对 CSS 进行解析,生成 CSSOM 规则树;
  3. 根据 DOM 树和 CSSOM 规则树构建 Render Tree。渲染树的节点被称为渲染对象,渲染对象是一个包含有颜色和大小等属性的矩形,渲染对象和 DOM 对象相对应,但这种对应关系不是一对一的,不可见的 DOM 元素不会被插入渲染树。
  4. 当渲染对象被创建并添加到树中,它们并没有位置和大小,所以当浏览器生成渲染树以后,就会根据渲染树来进行布局(也可以叫做回流)。这一阶段浏览器要做的事情就是要弄清楚各个节点在页面中的确切位置和大小。通常这一行为也被称为“自动重排”。
  5. 布局阶段结束后是绘制阶段,比那里渲染树并调用对象的 paint 方法将它们的内容显示在屏幕上,绘制使用 UI 基础组件。

注:为了更好的用户体验,渲染引擎会尽可能早的将内容呈现到屏幕上,并不会等到所有的 html 解析完成之后再去构建和布局 render tree。它是解析完一部分内容就显示一部分内容,同时可能还在网络下载其余内容。

如何实现浏览器内多个标签页之间的通信?

实现多个标签页之间的通信,本质上都是通过中介者模式来实现的。因为标签页之间没有办法直接通信,因此我们可以找一个中介者来让标签页和中介者进行通信,然后让这个中介者来进行消息的转发。

  1. 使用 Websocket,通信的标签页连接同一个服务器,发送消息到服务器后,服务器推送消息给所有连接的客户端;
  2. 可以地调用 localStorage,localStorage 在另一个浏览上下文里被添加、修改或删除时,它都会触发一个 storage 事件,我们可以通过监听 storage 事件,控制它的值来进行页面信息通信;
  3. 如果我们能够获得对应标签页的引用,通过 postMessage 方法也是可以实现多个标签页通信的;

如何简述前端性能优化?

页面内容方面

  • 通过文件合并、css 雪碧图、使用 base64 等方式来减少 HTTP 请求数,避免过多的请求造成等待的情况;
  • 通过 DNS 缓存等机制来减少 DNS 的查询次数;
  • 通过设置缓存策略,对常用不变的资源进行缓存;
  • 通过延迟加载的方式,来减少页面首屏加载时需要请求的资源,延迟加载的资源当用户需要访问时,再去请求加载;
  • 通过用户行为,对某些资源使用预加载的方式,来提高用户需要访问资源时的响应速度;

服务器方面

  • 使用 CDN 服务,来提高用户对于资源请求时的响应速度;
  • 服务器端自用 Gzip、Deflate 等方式对于传输的资源进行压缩,减少传输文件的体积;
  • 尽可能减小 cookie 的大小,并且通过将静态资源分配到其他域名下,来避免对静态资源请求时携带不必要的 cookie;

什么是 webp?

WebP 是谷歌开发的一种新图片格式,它是支持有损和无损两种压缩方式的使用直接色的点阵图。使用 webp 格式的最大优点是是,在相同质量的文件下,它拥有更小的文件体积。因此它非常适合于网络图片的传输,因为图片体积的减少,意味着请求时间的减少,这样会提高用户的体验。这是谷歌开发的一种新的图片格式。

浏览器如何判断是否支持 webp 格式图片?

通过创建 Image 对象,将其 src 属性设置为 webp 格式的图片,然后在 onload 事件中获取图片的宽高,如果能够获取,则说明浏览器支持 webp 格式图片。如果不能获取或者触发了 onerror 函数,那么就说明浏览器不支持 webp 格式的图片。

CSS

calc, support, media各自的含义及用法?

  • @support主要是用于检测浏览器是否支持CSS的某个属性,其实就是条件判断,如果支持某个属性,你可以写一套样式,如果不支持某个属性,你也可以提供另外一套样式作为替补。
  • calc() 函数用于动态计算长度值。 calc()函数支持 "+", "-", "*", "/"运算;
  • @media 查询,你可以针对不同的媒体类型定义不同的样式。

介绍下 BFC 及有什么应用?

BFC(Block Format Context)块级格式化上下文,是页面盒模型中的一种 CSS 渲染模式,相当于一个独立的容器,里面的元素和外部的元素相互不影响。

创建 BFC 的方式有:

  1. html 根元素
  2. float 浮动
  3. 绝对定位
  4. overflow 不为 visible
  5. display 为表格布局或者弹性布局;

BFC 主要的作用是:

  1. 清除浮动
  2. 防止同一 BFC 容器中的相邻元素间的外边距重叠问题

怎么让一个 div 水平垂直居中?

  1. //方案1 div绝对定位水平垂直居中 margin:auto实现绝对定位元素的居中
  2. div {
  3. width: 200px;
  4. height: 200px;
  5. background: pink;
  6. position: absolute;
  7. left: 0;
  8. top: 0;
  9. bottom: 0;
  10. right: 0;
  11. margin: auto;
  12. }
  1. //方案2 div绝对定位水平垂直居中 margin 负间距 较为流行
  2. div {
  3. width: 200px;
  4. height: 200px;
  5. background: pink;
  6. position: absolute;
  7. left: 50%;
  8. top: 50%;
  9. margin-left: -100px;
  10. margin-top: -100px;
  11. }
  1. //方案3 div绝对定位水平垂直居中 transforms 变形
  2. //兼容性:IE8不支持;
  3. div {
  4. width: 200px;
  5. height: 200px;
  6. background: green;
  7. position: absolute;
  8. left: 50%; /* 定位父级的50% */
  9. top: 50%;
  10. transform: translate(-50%, -50%); /*自己的50% */
  11. }

介绍下重绘和回流(Repaint & Reflow),以及如何进行优化?

浏览器渲染机制

  • 浏览器采用流式布局模型(Flow Based Layout);
  • 浏览器会把 HTML 解析成 DOM,把 CSS 解析成 CSSOM,DOM 和 CSSOM 合并就产生了渲染树(Render Tree);
  • 有了 RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上;
  • 由于浏览器使用流式布局,对 Render Tree 的计算通常只需要遍历一次就可以完成,但 table 及其内部元素除外,他们可能需要多次计算,通常要花 3 倍于同等元素的时间,这也是为什么要避免使用 table 布局的原因之一;

重绘,由于节点的集合属性发生改变或者由于样式改变而不会影响布局的,成为重绘,例如 outline、visibility、color、background-color 等,重绘的代价是高昂的,因此浏览器必须验证 DOM 树上其他节点元素的可见性。

浏览器优化,现代浏览器大多是通过队列机制来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新(即16.6ms)才会清空队列,但当你获取布局信息的时候,队列中可能会有影响这些属性或方法返回值的操作,即使没有,浏览器也会强制清空队列,触发回流和重绘来确保返回正确的值。

触发回流的场景,获取位置信息或者修改几何属性,如下:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
  • 获取位置信息,因为需要回流计算最新的值

例如 offsetTop、clientTop、scrollTop、getComputedStyle()、width、height、getBoundingClientRect(),应避免频繁使用这些属性,他们都会强制渲染刷新队列。

如何减少重绘和回流?

  • CSS

    • 使用 transform 代替 top
    • 使用 visibility 替换 display: none,前者引起重绘,后者引发回流;
    • 避免使用 table 布局;
    • 尽可能在 DOM 树的最末端改变 class
    • 避免设置多层内联样式,CSS 选择符从右往左匹配查找,避免节点层级过多;
    • 将动画效果应用到 position 属性为 absolutefixed 的元素上,避免影响其他元素的布局;
    • 避免使用 CSS 表达式,可能会引发回流;
    • CSS 硬件加速;
  • JavaScript

    • 避免频繁操作样式,修改 class 最好;
    • 避免频繁操作 DOM,合并多次修改为一次;
    • 避免频繁读取会引发回流/重绘的属性,将结果缓存;
    • 对具有复杂动画的元素使用绝对定位,使它脱离文档流;

分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景?

  • display: none不占空间,不能点击,会引起回流,子元素不影响
  • visibility: hidden占据空间,不能点击,引起重绘,子元素可设置 visible进行显示
  • opacity: 0 占据空间,可以点击,引起重绘,子元素不影响

如何简述CSS盒模型?

  • 盒子由 marginborderpaddingcontent组成;

  • 标准盒模型:box-sizing: content-box;

  • IE 盒模型:box-sizing: border-box;

1rem、1em、1vh、1px各自代表的含义?

  • rem是全部的长度都相对于根元素<html>元素。通常做法是给html元素设置一个字体大小,然后其他元素的长度单位就为rem。
  • em子元素字体大小的em是相对于父元素字体大小,元素的width/height/padding/margin用em的话是相对于该元素的font-size。
  • vw/vh全称是 Viewport Width 和 Viewport Height,视窗的宽度和高度,相当于 屏幕宽度和高度的 1%,不过,处理宽度的时候%单位更合适,处理高度的 话 vh 单位更好。
  • px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。

rem的转换原理是什么?

rem 是 CSS3 新增的相对长度单位,是指相对于根元素 htmlfont-size 计算值的大小。

默认根元素的 font-size 都是 16px的。如果想要设置 12px 的字体大小也就是 12px/16px = 0.75rem

  • 由于 px 是相对固定单位,字号大小直接被定死,无法随着浏览器进行缩放;
  • rem 直接相对于根元素 html,避开层级关系,移动端新型浏览器对其支持较好;

注:个人用 vw + 百分比布局用的比较多,可以使用 webpackpostcss-loader 的一个插件 postcss-px-to-viewport 实现对 pxvw 的自动转换,非常适合开发。

如何设置移动端视口配置?

  1. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  • initial-scale: 初始的缩放比例;
  • minimum-scale: 允许用户缩放到的最小比例;
  • maximum-scale: 允许用户缩放到的最大比例;
  • user-scalable: 用户是否可以手动缩放;

伪类和伪元素有什么区别?

伪类用于当已有元素处于某种状态时,为其添加对应的样式,这个状态是根据用户行为变化而变化的。比如说 :hover。它只有处于 dom 树无法描述的状态才能为元素添加样式,所以称为伪类。

伪元素用于创建一些原本不在文档树中的元素,并为其添加样式,比如说 ::before。虽然用户可以看到这些内容,但是其实他不在文档树中。

区别在于,伪类的操作对象是文档树中已存在的元素,而伪元素是创建一个文档树外的元素。css 规范中用双冒号 :: 表示伪元素,用一个冒号 : 表示伪类。

行内元素中的margin和padding和出现什么情况?

  • 水平方向:水平方向上,都有效;
  • 垂直方向:垂直方向上,都无效;(padding-toppadding-bottom 会显示出效果,但是高度不会撑开,不会对周围元素有影响)

CSS 中哪些属性可以继承?

  • 字体属性:font-family,font-size,font-weight,font-style
  • 文本属性:text-indent,text-align,line-height,word-spacing,letter-spacing,color
  • 其他:cursor,visibility

CSS加载有什么特点?

根据页面渲染流程可得知:

  • css加载不会阻塞DOM树的解析;
  • css加载会阻塞DOM树的渲染;
  • css加载会阻塞后面js语句的执行

CSS3 新增伪类有那些?

  • elem:nth-child(n): 选中父元素下的第 n 个标签名为elem的元素;
  • elem:nth-last-child(n): 作用同上,从后开始查找;
  • elem:last-child:最后一个子元素
  • elem:only-child:如果 elem 是父元素下唯一的子元素,则选中;
  • elem:nth-of-type(n):选择父元素下第 nelem 类型元素;
  • elem:empty:选中不包含子元素和内容的 elem类型元素;
  • :not(elem):选择非 elem元素的每个元素;
  • :enabled:启用状态的表单组件

min-width/max-width 和 min-height/max-height 属性间的覆盖规则?

  • max-width 会覆盖 width,即使 width是行内样式或者设置了 !important
  • min-width 会覆盖 max-width,此规则发生在 min-widthmax-width 冲突的时候;

浏览器

浏览器缓存读取规则是什么?

浏览器缓存可以优化性能,比如直接使用缓存而不发起请求,或者发起了请求但后端存储的数据和前端一致,则使用缓存从而减少响应数据。

缓存位置

Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker 的话,传输协议必须为 HTTPSService Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由缓存哪些文件、如何匹配缓存、如何读取缓存,而缓存是可持续性的。Service Worker 也是 PWA 的核心技术。

Memory Cache 也就是内存中的缓存,主要包含的是当前页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据很高效,但是缓存持续性很短,会随着进程的释放而释放。一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。

Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。在所有浏览器缓存中,Disk Cache 覆盖面基本上是最大的。它会根据 HTTP Header 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。绝大部分的缓存都来自 Disk Cache

Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被时候用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂(大约 5 分钟)。

缓存过程分析

浏览器与服务器通信的方式为应答模式,即是:浏览器发起 HTTP 请求 - 服务器响应该请求。浏览器第一次向服务器发起该请求后拿到请求结果后,将请求结果和缓存表示存入浏览器缓存,浏览器对于缓存的处理是根据第一次请求资源返回的响应头来确定的。

  • 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识;
  • 浏览器每次拿到返回的请求结果都会将该结果和缓存表示存入浏览器缓存中;

如何简述WebAssembly?

WebAssembly 是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如 C/C++ 等语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 Javascript 共存,允许两者一起工作。

WebAssembly 提供了一条途径,以使得以各种语言编写的代码都可以以接近原生的速度在 Web 中运行。

如何简述缓存?

所有的性能优化中,缓存是最重要也是最直接有效的,缓存机制相关的字段都是在请求和响应头上

  • 强缓存在缓存有效期内,客户端直接读取本地资源。强缓存返回的状态码是 200。

  • Expireshttp1.0 中使用,表示资源失效的具体时间点 Expires:Sat, 09 Jun 2018 08:13:56 GMT ,若是访问器和本地时间不一致,可能就会出现问题,在现在 http1.1中换成了 max-age ,为了兼容也可以加上。

  • Cache-control指定指令来实现缓存机制,多个指令间逗号分隔,常见的指令有以下几个

    • max-age: 强缓存的有效时间,单位秒 max-age=30672000
    • no-cache:使用缓存协商,先与服务器确认返回的响应是否被更改。
    • no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源,可用于关闭缓存。
    • public :表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存,即使是通常不可缓存的内容(例如,该响应没有max-age指令或Expires消息头)。
    • private :表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容。
  • 协商缓存关键在于协商,在使用本地缓存之前,需要先跟服务器做个对比,服务器告知你的资源可用,是最新的,那就可以直接取本地资源,反之,服务器返回最新的资源给客户端,客户端收到后更新本地资源。采用资源最后修改时间来判断,单位精度秒。

    • 若本地资源是最新的,那么返回 304

    • 若比对后,需要从服务器获取最新资源,那就是正常的 200

    • Last-Modified:服务器资源的最新更新时间 Tue, 14 Jan 2020 09:18:29 GMT

    • If-Modified-Since:客户端发起协商,把本地记录的文件更新时间传给服务器,服务器进行判断比较
      这个判断方式是 http1.0 的产物,因为时间精度是秒,若文件的更新频率在秒级以内,就会出现文件不一致。

    • ETag:服务器根据内容生成唯一的字符串标识(优先级优于Last-Modified)

    • If-None-Match:客户端发起协商,把本地记录的 hash 标识传给服务器,服务器进行判断比较。

如何简述PWA?

PWA(Progressive web apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。

App Shell 架构核心技术是构建 Progressive Web App 的一种方式,这种应用能可靠且即时地加载到您的用户屏幕上,与本机应用相似。这个模型包含界面所需要的最小资源文件,如果离线缓存,可以确保重复访问都有快速响应的特性,页面可快速渲染,网络仅仅获取数据。 App Shell 就类似于原生app,没网络也可以本地启动。

ServiceWork 持久的离线缓存的能力就可以实现。JS 是单线程的,ServiceWork 独立线程意味着不会阻塞js执行;可编程拦截代理请求和返回,可自定义文件缓存策略。

  • 一个独立的 worker 线程,独立于当前网页进程,有自己独立的 worker context
  • 一旦被 install,就永远存在,除非被手动 unregister
  • 用到的时候可以直接唤醒,不用的时候自动睡眠
  • 可编程拦截代理请求和返回,缓存文件,缓存的文件可以被网页进程取到(包括网络离线状态)
  • 离线内容开发者可控
  • 能向客户端推送消息
  • 不能直接操作 DOM
  • 必须在 HTTPS 环境下才能工作
  • 异步实现,内部大都是通过 Promise 实现

设计缓存策略:

  1. 缓存优先,先查询缓存,若存在,直接返回,不存在,请求服务,更新缓存
  2. 服务端优先,不查询缓存,直接请求服务端,服务端失败才会查询缓存
  3. 稳定优先,先查询缓存,有就读取,同时请求服务端更新资源

网络

为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?

  1. 能够完成整个 HTTP 请求+响应(尽管不需要响应内容);
  2. 触发 GET 请求之后不需要获取和处理数据,服务器也不需要发送数据;
  3. 跨域友好;
  4. 执行过程无阻塞;
  5. 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好;
  6. GIF 的最低合法体积最小(合法的 GIF 只需要 43 个字节)

如何解决跨域问题?

  1. JSONP
  2. CORS(Cross-Origin-Resource-Share,跨域资源共享),由服务端设置响应头通过浏览器的同源策略限制

    • Access-Control-Allow-Origin: *;
    • Access-Control-Allow-Methods: *;
    • Access-Control-Allow-Headers: *;
    • Access-Control-Allow-Credentials: true;

什么是 CSRF 攻击?如何防范 CSRF 攻击?

CSRF 攻击指的是跨站请求伪造攻击,攻击者诱导用户进入一个第三方网站,然后该网站向被攻击网站发送跨站请求。如果用户在被攻击网站中保存了登录状态,那么攻击者就可以利用这个登录状态(cookie),绕过后台的用户验证,冒充用户向服务器执行一些操作。

CSRF 攻击的本质是利用了 cookie 会在同源请求中携带发送给服务器的特点,以此来实现用户的冒充。

防护方法:

  1. 同源检测,服务器检测请求来源;
  2. 使用 token 来进行验证;
  3. 设置 cookie 时设置 Samesite,限制 cookie 不能作为被第三方使用;

如何计算页面的可用性时间?

Performance 接口可以获取到当前页面中与性能相关的信息。

  • Performance.timing:Performance.timing 对象包含延迟相关的性能信息;

懒加载是什么?有什么作用?

懒加载也叫延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。

懒加载的优点:

  • 提升用户体验,加快首屏渲染速度;
  • 减少无效资源的加载;
  • 防止并发加载的资源过多会阻塞 js 的加载;

懒加载的原理: 首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在 data-original 属性中,当页面滚动的时候需要去监听 scroll 事件,在 scroll 事件的回调中,判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内则将图片的 src 属性设置为 data-original 的值,这样就可以实现延迟加载。

如何简述http 协议?

http 是建立在 TCP 上的应用层协议,超文本传送协议。是单向的短链接。

  • HTTP1.0 :客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
  • HTTP1.1 :可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求
  • HTTP2.0 :可支持多路复用,一个 tcp 可同时传输多个 http 请求,头部数据还做了压缩

HTTP1.0 和 HTTP1.1 有什么区别?

HTTP1.0 最早在网页中使用是在 1996 年,那个时候只是使用一些较为简单的网页上和网络请求上。而 HTTP1.1 则在 1999 年才开始广泛应用于现在的各大浏览器网络请求中,同时 HTTP1.1 也是当前使用最为广泛的 HTTP 协议。主要区别体现在:

  • 缓存处理:在 HTTP1.0 中主要使用 header 里的 If-Modified-SinceExpires 来作为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略例如 Entity tagIf-Unmodified-SinceIf-MatchIf-None-Match 等更多可供选择的缓存头来控制缓存策略。
  • 带宽优化及网络连接的使用:HTTP1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,而且不支持断点续传功能,HTTP1.1 则在请求头中引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
  • 错误通知的管理:在 HTTP1.1 中新增了 24 个错误状态响应码,如 409(Conflict) 表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器的某个资源被永久性的删除;
  • Host 头处理:在 HTTP1.0 中认为每台服务器都绑定唯一的 IP 地址,因此,请求信息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们可以共享一个 IP 地址。HTTP1.1 的请求信息和响应信息都应支持 Host 头域,且请求信息中如果没有 Host 头域会报告一个错误(400 Bad Request)。
  • 长连接:HTTP1.1 支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟,在 HTTP1.1 中默认开启 Connection: keep-alive,一定程度上弥补了 HTTP1.0 每次请求都要创建连接的缺点。

如何简述TCP?

tcp 是传输层协议,它的特点是:三次握手和四次挥手。三次握手的目的是为了防止已经失效的连接请求报文段突然又传到服务端,而产生错误,所以要建立可靠的连接发送数据

三次握手建立连接过程:

  1. 客户端发送位码为syn=1,随机产生数据包到服务器,服务器由SYN=1知道客户端要求建立联机(客户端:我要连接你)
  2. 服务器收到请求后要确认联机信息,向A发送ack number=(客户端的seq+1),syn=1,ack=1,随机生成数据包(服务器:好的,你来连吧)
  3. 客户端收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,客户端会再发送ack number=(服务器的seq+1),ack=1,服务器收到后确认seq值与ack=1则连接建立成功。(客户端:好的,我来了)

四次挥手断开连接的过程:

  1. 客户端发送请求给服务端,申请主动断开连接,进入等待状态,不在往服务端发送数据,但是接收数据(客户端:我要断开连接了)
  2. 服务端收到后,告知客户端知道了,服务端进行等待状态,不在接收数据,但是可以继续发送数据(服务端:好,我知道了,但是要等一等)
  3. 客户端收到服务端的告知后,进入下一阶段的等待。(客户端:好,我等)
  4. 服务端完成剩余数据的发送后,告知客户端可以断开了,服务端不接收和读取数据(服务端:你可以断开了)
  5. 客户端收到后,告知服务端,已收到,然后释放链接(客户端:好的,我断开链接了)
  6. 服务端收到后,也释放链接

HTTPS 握手有哪些过程?

  1. 客户端使用 httpsurl 访问 web服务器,要求与服务器建立 ssl 连接;
  2. web服务器收到客户端请求后,会将网站的证书(包含公钥)传送一份给客户端;
  3. 客户端收到网站证书后会检查证书的颁发机构以及过期时间,如果没有问题就随机产生一个秘钥;
  4. 客户端利用公钥将会话秘钥加密,并传送给服务端,服务端利用自己的私钥解密出会话秘钥;
  5. 之后服务器与客户端使用秘钥加密传输;

HTTPS 握手过程中,客户端如何验证证书的合法性?

  1. 首先浏览器读取证书中的证书所有者、有效期等信息进行校验,校验证书的网站域名是否与证书颁发的域名一致,校验证书是否在有效期内;
  2. 浏览器开始查找操作系统中已内置的受新人的证书发布机构 CA,与服务器发来的证书中的颁发者 CA 比对,用于校验证书是否为合法机构颁发;
  3. 如果找不到,浏览器就会报错,说明浏览器发来的证书是不可信任的;
  4. 如果找到,那么浏览器就会从操作系统中取出颁发者 CA 的公钥(多数浏览器开发商发布版本时,会实现在内部植入常用认证机关的公开密钥),然后对服务器发来的证书里面的签名进行解密;
  5. 浏览器使用相同的 hash 算法计算出服务器发来的证书的 hash 值,将这个计算的 hash 值与证书中签名做对比;
  6. 对比结果一致,则证明服务器发来的证书合法,没有被冒充;

如何简述UDP?

传输层的另外一个协议 UDP 称为用户数据报协议,无连接的传输协议。UDP 是报文的搬运工,不需要建立完全可靠的链接,不保证数据的可靠性,因为协议控制项比较少,且报文头部简单,报文体积相对要小,速度上相比更快,实时性更高,比如电话会议、多媒体数据流等场景

如何实现 token 加密?

通过JWT 加密:

  1. 需要一个 secret(随机数);
  2. 后端利用 secret 和加密算法(如:HMAC-SHA256)对 payload(如账号密码)生成一个字符串(token),返回前端;
  3. 前端每次 request 在 header 中带上 token;
  4. 后端用同样的算法解密;

如何简述HTTPS 中间人攻击?

https 协议由 http + ssl 协议构成。

中间人攻击过程如下:

  1. 服务器向客户端发送公钥;
  2. 攻击者截获公钥,保留在自己手上;
  3. 然后攻击者自己生成一个【伪造的】公钥,发给客户端;
  4. 客户端收到伪造的公钥后,生成加密 hash(秘钥) 值发给服务器;
  5. 攻击者获得加密 hash 值,用自己的私钥解密获得真秘钥;
  6. 同时生成假的加密 hash 值,发给服务器;
  7. 服务器用私钥解密获得假秘钥;
  8. 服务器用假秘钥加密传输信息;

防范方法在于服务器在发送浏览器的公钥中加入 CA 证书,浏览器可以验证 CA 证书的有效性;(现有 HTTPS 很难被劫持,除非信任了劫持者的 CA 证书)。

HTTP 有哪些状态码及其功能?

状态码 描述
1XX 信息,服务器收到请求,需要请求者继续执行操作
2XX 成功,操作被成功接收并处理
3XX 重定向,需要进一步的操作已完成请求
4XX 客户端错误,请求包含语法错误或无法完成请求
5XX 服务器错误,服务器在处理请求的过程中发生了错误

输入URL到页面加载经历哪些过程?

  1. 域名解析,找到服务地址
  2. 构建 TCP 连接,若有 https,则多一层 TLS 握手,
  3. 特殊响应码处理 301 302
  4. 解析文档
  5. 构建 dom 树和 csscom
  6. 生成渲染树:从DOM树的根节点开始遍历每个可见节点,对于每个可见的节点,找到CSSOM树中对应的规则,并应用它们,根据每个可见节点以及其对应的样式,组合生成渲染树
  7. Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的集合信息
  8. Painting(重绘):根据渲染树及其回流得到的集合信息,得到节点的绝对像素。
  9. 绘制,在页面上展示,这一步还涉及到绘制层级、GPU相关的知识点
  10. 加载js脚本,加载完成解析js脚本

HTTP2.0 与 HTTP1.1 相较于之前版本有哪些改进?

  • HTTP2.0

    • HTTP2.0 基本单位为二进制,以往是采用文本形式,健壮性不是很好,现在采用二进制格式,更方便更健壮。
    • HTTP2.0 的多路复用,把多个请求当做多个流,请求响应数据分成多个帧,不同流中的帧交错发送,解决了 TCP 连接数量多,TCP 连接慢,所以对于同一个域名只用创建一个连接就可以了。
    • HTTP2.0 压缩消息头,避免了重复请求头的传输,又减少了传输的大小;
    • HTTP2.0 服务端推送,浏览器发送请求后,服务端会主动发送与这个请求相关的资源,之后浏览器就不用再次发送后续的请求了;
    • HTTP2.0 可以设置请求优先级,可以按照优先级来解决阻塞的问题;
  • HTTP1.1

    • 缓存处理新增 E-Tag、If-None-Match 之类的缓存来来控制缓存;
    • 长连接,可以在一个 TCP 连接上发送多个请求和响应;