写在前面

此文章的题是同事给我发的一个PDF文档里的题,原版我也不清楚是哪里的,好像是某个培训机构的题库。题比较全,但是原版很多题的答案不是很清晰,在此基础上我重新补充了一下

最近应该会持续的把这些题的答案更新完

2023.2.17

前端基础

一、 HTTP/HTML/浏览器

1、说一下 http 和 https

https 的 SSL 加密是在传输层实现的。

(1) http 和 https 的基本概念

  • http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
  • https: 是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即HTTP 下加入SSL层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。https 协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。

(2) http 和 https 的区别?

http 传输的数据都是未加密的,也就是明文的,网景公司设置了SSL 协议来对http 协议传输的数据进行加密处理,简单来说 https 协议是由 http 和 ssl 协议构建的可进行加密传输和身份认证的网络协议,比 http 协议的安全性更高

主要的区别如下:

  • Https 协议需要 ca 证书,费用较高。
  • http 是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl 加密传输协议。使用不同的链接方式,端口也不同,一般而言,http 协议的端口为80,https 的端口为443
  • http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。

(3) https 协议的工作原理

客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤:

  • 客户使用 https url 访问服务器,则要求 web 服务器建立 ssl 链接
  • web 服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),返回或者说传输给客户端。
  • 客户端和 web 服务器端开始协商 SSL 链接的安全等级,也就是加密等级。
  • 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
  • web 服务器通过自己的私钥解密出会话密钥。
  • web 服务器通过会话密钥加密与客户端之间的通信。

(4) https 协议的优点

  • 使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
  • HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比http 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
  • HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
  • 谷歌曾在 2014 年 8 月份调整搜索引擎算法,并称“比起同等 HTTP 网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。

(5) https 协议的缺点

  • https 握手阶段比较费时,会使页面加载时间延长 50%,增加 10%~20%的耗电
  • https 缓存不如 http 高效,会增加数据开销。
  • SSL 证书也需要钱,功能越强大的证书费用越高。
  • SSL 证书需要绑定 IP,不能再同一个 ip 上绑定多个域名,ipv4 资源支持不了这种消耗。

2、tcp 三次握手,一句话概括

确认客户端和服务端的接收与发送能力是否正常,因此需要三次握手。

简化三次握手:

从图片可以得到三次握手可以简化为:C发起请求连接S确认,S也发起请求连接C确认

每次握手的作用:

  • 第一次握手: S只可以确认 自己可以接收C发送的报文段
    (客户端给服务器发送一个 SYN 报文)
    (服务器收到 SYN 报文之后,会应答一个 SYN+ACK 报文。)
  • 第二次握手:C可以确认 S收到了自己的报文段,并且可以确认自己可以接受S发送的报文段
    (客户端收到 SYN+ACK 报文之后,会回应一个 ACK 报文。)
  • 第三次握手:S可以确认C收到了自己发送的报文段
    (服务器收到 ACK 报文之后,三次握手建立完成。)

3、TCP 和 UDP 的区别

  1. TCP 是面向连接的,udp 是无连接的即发送数据前不需要先建立链接。
  2. TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付。并且因为tcp 可靠,面向连接,不会丢失数据因此适合大数据量的交换。
  3. TCP 是面向字节流,UDP 面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如 IP 电话和视频会议等)。
  4. TCP 只能是 1 对 1 的,UDP 支持 1 对 1,1 对多。
  5. TCP 的首部较大为 20 字节,而 UDP 只有 8 字节。
  6. TCP 是面向连接的可靠性传输,而 UDP 是不可靠的。

4、WebSocket 的实现和应用

(1) 什么是 WebSocket?

WebSocket 是 HTML5 中的协议,支持持久连续,http 协议不支持持久性连接。Http1.0和 HTTP1.1 都不支持持久性的链接,HTTP1.1 中的 keep-alive,将多个http 请求合并为1 个

(2) WebSocket 是什么样的协议,具体有什么优点?

HTTP 的生命周期通过 Request 来界定,也就是 Request 一个 Response,那么在Http1.0协议中,这次 Http 请求就结束了。在 Http1.1 中进行了改进,是的有一个connection:Keep-alive,也就是说,在一个 Http 连接中,可以发送多个 Request,接收多个Response。但是必须记住,在 Http 中一个 Request 只能对应有一个 Response,而且这个Response是被动的,不能主动发起。

WebSocket 是基于 Http 协议的,或者说借用了 Http 协议来完成一部分握手,在握手阶段与 Http 是相同的。我们来看一个 websocket 握手协议的实现,基本是2 个属性,upgrade,connection。

基本请求如下:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

多了下面 2 个属性:

Upgrade:webSocket
Connection:Upgrade

告诉服务器发送的是websocket

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

5、HTTP 请求的方式

HTTP 请求方式一共有 9 种,分别为 POST 、GET 、HEAD、PUT 、PATCH 、 OPTIONS 、DELETE 、CONNECT 、 TRACE 。
其中前三种 POST 、GET 、HEAD 是 HTTP 1.0 定义的,后六种 PUT 、PATCH 、 OPTIONS 、DELETE 、CONNECT 、 TRACE 是 HTTP 1.1 定义的。

  • POST :表示向指定资源提交数据,数据包含在请求头中。有可能导致新的资源建立或原有资源修改。 POST 请求是 HTTP 请求中使用最多的一种请求方式。
  • GET :表示请求指定的页面信息,并返回实体内容。
  • HEAD :类似于 GET,只不过返回的响应体中没有具体内容,只有报文头,用于获取报文头。
  • PUT :从客户端向服务器传送的数据取代指定的内容,即向指定的位置上传最新的内容。
  • PATCH :对 PUT 方法的补充,用来对已知资源进行局部更新。
  • OPTIONS :返回服务器针对特殊资源所支持的 HTML 请求方式 或 允许客户端查看服务器的性能。
  • DELETE :请求服务器删除 Request-URL 所标识的资源。
  • CONNECT :HTTP 1.1 中预留给能够将连接改为管道方式的代理服务器。
  • TRACE :回显服务器收到的请求,主要用于测试和诊断。

6、一个图片 url 访问后直接下载怎样实现?

请求的返回头里面,用于浏览器解析的重要参数就是 OSS 的 API 文档里面的返回http头,决定用户下载行为的参数。

下载的情况下:

  1. x-oss-object-type: Normal
  2. x-oss-request-id: 598D5ED34F29D01FE2925F41
  3. x-oss-storage-class: Standard

7、说一下 web Quality(无障碍)

能够被残障人士使用的网站才能称得上一个易用的(易访问的)网站。残障人士指的是那些带有残疾或者身体不健康的用户。
使用 alt 属性:

<img src="person.jpg" alt="this is a person"/>

有时候浏览器会无法显示图像。具体的原因有:

  • 用户关闭了图像显示
  • 浏览器是不支持图形显示的迷你浏览器
  • 浏览器是语音浏览器(供盲人和弱视人群使用)
  • 如果您使用了 alt 属性,那么浏览器至少可以显示或读出有关图像的描述。

8、几个很实用的 BOM 属性对象方法?

(1)什么是 Bom?

Bom 是浏览器对象。

(2) 有哪些常用的 Bom 属性呢?

1. location 对象

  • location.href-- 返回或设置当前文档的 URL
  • location.search – 返回 URL 中的查询字符串部分。例如 http://www.baidu.com/baidu.php?id=5&name=baidu 返回包括(?)后面的内容?id=5&name=baidu
  • location.hash – 返回 URL#后面的内容,如果没有#,返回空
  • location.host – 返回 URL 中的域名部分,例如 www.baidu.com
  • location.hostname – 返回 URL 中的主域名部分,例如 baidu.com
  • location.pathname – 返回 URL 的域名后的部分。例如 http://www.baidu.com/xhtml/ 返回/xhtml/
  • location.port – 返回 URL 中的端口部分。例如 http://www.baidu.com:8080/xhtml/ 返回8080
  • location.protocol – 返回 URL 中的协议部分。例如 http://www.baidu.com:8080/xhtml/ 返回(//)前面的内容 http:
  • location.assign – 设置当前文档的 URL
  • location.replace() – 设置当前文档的 URL,并且在 history 对象的地址列表中移除这个URL location.replace(url);
  • location.reload() – 重载当前页面

2. history 对象

  • history.go() – 前进或后退指定的页面数 history.go(num);
  • history.back() – 后退一页
  • history.forward() – 前进一页

3. Navigator 对象

  • navigator.userAgent – 返回用户代理头的字符串表示(就是包括浏览器版本信息等的字符串)
  • navigator.cookieEnabled – 返回浏览器是否支持(启用)cookie

4. window 对象

  • alert(str):用于向用户展示一些用户不可控的警告信息
  • confirm(str):用于向用户展示一段信息并确认结果
  • prompt(str,str): 用于向用户展示一段信息并收集用户输入结果
  • print(): 显示打印对话框(等同与点击浏览器菜单栏打印选项)
  • find(): 显示查找对话框(等同与点击浏览器菜单栏查找选项)

9、说一下 HTML5 drag api

让一个元素被拖拽需要添加 draggable 属性,再加上全局事件处理函数如下

<p id="p1" draggable="true">This element is draggable.</p>
  • dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发,。
  • darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
  • dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
  • dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
  • dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
  • drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
  • dragend:事件主体是被拖放元素,在整个拖放操作结束时触发

10、说一下 http2.0

首先补充一下,http 和 https 的区别,相比于 http,https 是基于 ssl 加密的http 协议

简要概括:http2.0 是基于 1999 年发布的 http1.0 之后的首次更新。

  • 提升访问速度:相比HTTP1.0,请求资源所需时间更少,访问速度更快。
  • 允许多路复用:多路复用允许同时通过单一的HTTP/2连接发送多重请求-响应信息。改善了在HTTP1.1中,浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制(连接数量),超过限制会被阻塞。
  • 二进制分帧:HTTP2.0会将所有的传输信息分割为更小的信息或者帧,并对他们进行二进制编码。
  • 首部压缩:使报头更紧凑,更快速传输,有利于移动网络环境。
  • 服务器端推送(server push):还没有收到浏览器的请求,服务器就把各种资源推送给浏览器。 比如,浏览器只请求了index.html,但是服务器把index.html、style.css、example.png全部发送给浏览器。

11、HTTP状态码

1. 下面是常见的 HTTP 状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误

2. HTTP 状态码分类

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599):

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

3. HTTP状态码列表:

状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

12、fetch 发送 2 次请求的原因

之所以会发送2次请求,那是因为我们使用了带预检(Preflighted)的跨域请求。该请求会在发送真实的请求之前发送一个类型为OPTIONS的预检请求。预检请求会检测服务器是否支持我们的真实请求所需要的跨域资源,唯有资源满足条件才会发送真实的请求。

13、 Cookie、sessionStorage、localStorage 的区别

相同点:
存储在客户端

不同点

  1. 生命周期:
    Cookie:可设置失效时间,否则默认为关闭浏览器后失效
    Localstorage:除非被手动清除,否则永久保存
    Sessionstorage:仅在当前网页会话下有效,关闭页面或浏览器后就会被清除
  2. 存放数据:
    Cookie:4k 左右
    Localstorage 和 sessionstorage:可以保存 5M 的信息
  3. http 请求:
    Cookie:每次都会携带在 http 头中,如果使用 cookie 保存过多数据会带来性能问题其他两个:仅在客户端即浏览器中保存,不参与和服务器的通信
  4. 易用性:
    Cookie:需要程序员自己封装,原生的 cookie 接口不友好
    其他两个:即可采用原生接口,亦可再次封装
  5. 应用场景:
    从安全性来说,因为每次 http 请求都回携带 cookie 信息,这样子浪费了带宽,所以cookie应该尽可能的少用,此外 cookie 还需要指定作用域,不可以跨域调用,限制很多,但是用户识别用户登陆来说,cookie还是比storage好用,其他情况下可以用storage,localstorage可以用来在页面传递参数,sessionstorage 可以用来保存一些临时的数据,防止用户刷新页面后丢失了一些参数。

14、cookie 的作用

  • 保存用户登录状态
    例如将用户 id 存储于一个 cookie 内,这样当用户下次访问该页面时就不需要重新登录了,现在很多论坛和社区都提供这样的功能。cookie 还可以设置过期时间,当超过时间期限后,cookie 就会自动消失。因此,系统往往可以提示用户保持登录状态的时间:常见选项有一个月、三个 月、一年等。
  • 跟踪用户行为
    例如一个天气预报网站,能够根据用户选择的地区显示当地的天气情况。如果每次都需要选择所在地是烦琐的,当利用了 cookie 后就会显得很人性化了,系统能够记住上一次访问的地区,当下次再打开该页面时,它就会自动显示上次用户所在地区的天气情况。因为一切都是在后 台完成,所以这样的页面就像为某个用户所定制的一样,使用起来非常方便定制页面。如果网站提供了换肤或更换布局的功能,那么可以使用 cookie 来记录用户的选项,例如:背景色、分辨率等。当用户下次访问时,仍然可以保存上一次访问的界面风格。

15、说一下 web worker

Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。

Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。

(1) 如何创建 web worker

  • 检测浏览器对于 web worker 的支持性
if (typeof(Worker) !== "undefined") {// Yes! Web worker support!// Some code.....
} else {// Sorry! No Web Worker support..
}
  • 创建 Web Worker 文件
    该脚本存储在 “demo_workers.js” 文件中,通常 web worker 不用于这种简单的脚本,而是用于 CPU 密集型任务。
let i = 0;function timedCount() {i ++;postMessage(i); //用于将消息发送回 HTML 页面。setTimeout("timedCount()",500);
}timedCount();
  • 创建 Web Worker 对象
    以下代码行检查 worker 是否已存在,如果不存在,它会创建一个新的 web worker 对象并运行 “demo_workers.js” 中的代码:
if (typeof(w) == "undefined") {w = new Worker("demo_workers.js");
}

完整

<!DOCTYPE html>
<html>
<body><p>Count numbers: <output id="result"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button><script>
let w;function startWorker() {if (typeof(w) == "undefined") {w = new Worker("demo_workers.js");}//向 web worker 添加一个 "onmessage" 事件侦听器。//当 Web Worker 发布消息时,将执行事件侦听器中的代码。来自 Web Worker 的数据存储在 event.data 中。w.onmessage = function(event) {document.getElementById("result").innerHTML = event.data;};
}function stopWorker() {w.terminate();w = undefined;
}
</script></body>
</html>

16、对 HTML 语义化标签的理解

HTML5 语义化标签是指正确的标签包含了正确的内容,结构良好,便于阅读,比如nav表示导航条,类似的还有 article、header、footer 等等标签。

语义化的优点:

  • 在没CSS样式的情况下,页面整体也会呈现很好的结构效果
  • 代码结构清晰,易于阅读,
  • 利于开发和维护 方便其他设备解析(如屏幕阅读器)根据语义渲染网页。
  • 有利于搜索引擎优化(SEO),搜索引擎爬虫会根据不同的标签来赋予不同的权重

17、iframe 是什么?有什么缺点?

定义: iframe 元素会创建包含另一个文档的内联框架

提示: 可以将提示文字放在 < iframe> < /iframe> 之间,来提示某些不支持iframe 的浏览器

缺点:

  • 会阻塞主页面的 onload 事件
  • 搜索引擎无法解读这种页面,不利于 SEO
  • iframe 和主页面共享连接池,而浏览器对相同区域有限制所以会影响性能。

18、Doctype 作用?严格模式与混杂模式如何区分?它们有何意义?

Doctype 声明于文档最前面,告诉浏览器以何种方式来渲染页面,这里有两种模式,严格模式和混杂模式。

  • 严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
  • 混杂模式,向后兼容,模拟老式浏览器,防止浏览器无法兼容页面。

19、Cookie 如何防范 XSS 攻击

XSS(跨站脚本攻击)是指攻击者在返回的 HTML 中嵌入 javascript 脚本,为了减轻这些攻击,需要在 HTTP 头部配上,set-cookie:

  • httpOnly-这个属性可以防止 XSS,它会禁止 javascript 脚本来访问cookie
  • secure - 这个cookie只能用https协议发送给服务器,用http协议是不发送的

20、Cookie 和 session 的区别

HTTP 是一个无状态协议,因此 Cookie 的最大的作用就是存储; sessionId 用来唯一标识用户。

  1. session 在服务器端,cookie 在客户端(浏览器)
  2. session 默认被存在在服务器的一个文件里(不是内存)
  3. session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
  4. session 可以放在 文件、数据库、或内存中都可以。
  5. 用户验证这种场合一般会用 session
  6. cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行COOKIE 欺骗考虑到安全应当使用 session。
  7. session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用 COOKIE

21、一句话概括 RESTFUL

就是用 URL 定位资源,用 HTTP对服务器端的资源进行操作,实现服务器端上资源的“表现层状态转移”

22、讲讲 viewport 和移动端布局

具体可以参考下面这篇文章
https://github.com/forthealllight/blog/issues/13

上面文章总结: 常用的自适应解决方案包括媒体查询、百分比、rem和vw/vh等。

1. px和视口

像素:我们在js或者css代码中使用的px单位就是指的是css像素,物理像素也称设备像素,只与设备或者说硬件有关,同样尺寸的屏幕,设备的密度越高,物理像素也就越多。

  • css像素:为web开发者提供,在css中使用的一个抽象单位
  • 物理像素:只与设备的硬件密度有关,任何设备的物理像素都是固定的

视口:广义的视口,是指浏览器显示内容的屏幕区域,狭义的视口包括了布局视口、视觉视口和理想视口

  1. 布局视口:pc网页在移动端的默认布局为980px
  2. 视觉视口:浏览器内看到的网站的显示区域,用户可以通过缩放来查看网页的显示内容,从而改变视觉视口
  3. 理想视口:在移动设备中就是指设备的分辨率,给定设备物理像素的情况下,最佳的“布局视口”
(1) 在移动端中,理想视口或者说分辨率跟物理像素之间有什么关系呢?

DPR(Device pixel ratio)设备像素比

1 DPR = 物理像素/分辨率
1 CSS像素 = 物理像素/分辨率  (不缩放的情况下)
(2) px与自适应

在pc端的布局视口通常情况下为980px,移动端以iphone6为例,分辨率为375 * 667,也就是说布局视口在理想的情况下为375px。比如现在我们有一个750px * 1134px的视觉稿,那么在pc端,一个css像素可以如下计算:

PC端: 1 CSS像素 = 物理像素/分辨率 = 750 / 980 =0.76 px
iphone6:1 CSS像素 = 物理像素 /分辨率 = 750 / 375 = 2 px

不同的移动设备分辨率不同,也就是1个CSS像素可以表示的物理像素是不同的,因此如果在css中仅仅通过px作为长度和宽度的单位,造成的结果就是无法通过一套样式,实现各端的自适应

2、媒体查询

使用@media媒体查询可以针对不同的媒体类型定义不同的样式,特别是响应式页面,可以针对不同屏幕的大小,编写多套样式,从而达到自适应的效果

但是媒体查询的缺点也很明显,如果在浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。

3、百分比

为了了解百分比布局,首先要了解的问题是:

(1)css中的子元素中的百分比(%)到底是谁的百分比?
  1. height或width,是相对于子元素的直接父元素的height或width
  2. top和bottom 、left和right
    子元素的top和bottom如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度
    子元素的left和right如果设置百分比,则相对于直接非static定位(默认定位的)父元素的宽度
  3. padding或margin:子元素的padding或者margin如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关
  4. border-radius:如果设置border-radius为百分比,则是相对于自身的宽度
(2)百分比单位布局应用

(3)百分比单位缺点
  1. 计算困难,如果我们要定义一个元素的宽度和高度,按照设计稿,必须换算成百分比单位。
  2. 各个属性中如果使用百分比,相对父元素的属性并不是唯一的。比如width和height相对于父元素的width和height,而margin、padding不管垂直还是水平方向都相对比父元素的宽度、border-radius则是相对于元素自身等等,造成我们使用百分比单位容易使布局问题变得复杂。

4、自适应场景下的rem解决方案

rem是一个灵活的、可扩展的单位,由浏览器转化像素并显示。与em单位不同,rem单位无论嵌套层级如何,都只相对于浏览器的根元素(HTML元素)的font-size。当页面的size发生变化时,只需要改变font-size的值,那么以rem为固定单位的元素的大小也会发生响应的变化。默认情况下,html元素的font-size为16px,所以:

 1 rem = 16pxhtml{ font-size: 62.5% }    //为了计算方便,通常可以将html的font-size设置62.5%1 rem = 10px     //上述情况下

但是在使用时,如果我们使用rem单位,每次都要把设计稿的px计算之后转换为rem,这样就很麻烦,我们可以在使用的时候依旧用px单位,然后把px再转化为rem

转换的插件:px2rem-loader postcss-loader

5、通过vw/vh来实现自适应

  • vw 相对于视窗的宽度,视窗宽度是100vw
  • vh 相对于视窗的高度,视窗高度是100vh
  • vmin vw和vh中的较小值
  • vmax vw和vh中的较大值

vw单位换算

  1. 如果要将px换算成vw单位,对于iphone6/7 375*667的分辨率
1px = (1/375)*100 vw
  1. postcss-px-to-viewport插件

23、click 在 ios 上有 300ms 延迟,原因及如何解决?

原因:2007年苹果发布首款Iphone上ios搭载的safari,采用了双击缩放的方案。

手机端浏览器不能区分用户的单机操作还是双击操作,所以设置了300ms的延迟时间,用来判断用户是点击还是双击。浏览器会在捕获用户第一次单击时,开启300ms定时,若300ms捕获不到第二次单继,则判断用户就是单击操作;若在300ms内,用户有第二次单继操作,则对区域进行缩放操作

解决方法:

  1. 禁止缩放
<meta name="viewport" content="width=device-width,user-scalable=no">
  1. css属性解决

touch-action:none那么当触控事件发生在元素上时,不进行任何操作——即不会出现滑动和缩放的效果

touch-action:none; //
  1. 使用FastClick插件

原理: 在检测到touchend事件的时候,会通过DOM自定义事件立即发出模拟一个click事件,并把300ms之后发出的click事件阻止掉。

但是使用FastClick,就会发现一个缺点: 在某些ios上,点击输入框启动键盘,触点不是很灵敏,必须重压或者长按才能成功唤启,快速点击是不会唤起软键盘的

解决: 在引用fastClick模块后,重写focus方法

24、addEventListener 参数

addEventListener(event, function, useCapture)

event 指定事件名;function 指定要事件触发时执行的函数;useCapture 指定事件是否在捕获或冒泡阶段执行。

25、http 常用请求头

  1. Accept 可接受的响应内容类型(Content-Types)。
    Accept: application/json 浏览器可以接受服务器回发的类型为 application/json。
    Accept: / 代表浏览器可以处理所有类型,(一般浏览器发给服务器都是发这个)。

  2. Accept-Charset 可接受的字符集

  3. Accept-Encoding 可接受的响应内容的编码方式。
    Accept-Encoding: gzip, deflate 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码)。

  4. Accept-Language 可接受的响应内容语言列表。
    Accept-Language:zh-CN,zh;q=0.9 浏览器申明自己接收的语言。

  5. Accept-Datetime 可接受的按照时间来表示的响应内容版本

  6. Authorization 用于表示 HTTP 协议中需要认证资源的认证信息

  7. Cache-Control 用来指定当前的请求/回复中的,是否使用缓存机制。

  8. Connection 客户端(浏览器)想要优先使用的连接类型
    Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
    Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。

  9. Cookie 由服务器通过Set-Cookie设置,用来存储一些用户信息以便让服务器辨别用户身份的

  10. Content-Length 以 8 进制表示的请求体的长度

  11. Content-MD5 请求体的内容的二进制 MD5 散列值(数字签名),以Base64 编码的结果

  12. Content-Type 请求体的 MIME 类型 (用于 POST 和PUT 请求中)

  13. Date 发送该消息的日期和时间(以 RFC 7231 中定义的"HTTP 日期"格式来发送)

  14. Expect 表示客户端要求服务器做出特定的行为

  15. From 发起此请求的用户的邮件地址

  16. Host 表示服务器的域名以及服务器所监听的端口号。如果所请求的端口是对应的服务的标准端口(80),则端口号可以省略。

  17. If-Match 仅当客户端提供的实体与服务器上对应的实体相匹配时,才进行对应的操作。主要用于像 PUT 这样的方法中,仅当从用户上次更新某个资源后,该资源未被修改的情况下,才更新该资源。

  18. If-Modified-Since 允许在对应的资源未被修改的情况下返回304 未修改

  19. If-None-Match 允许在对应的内容未被修改的情况下返回304 未修改(304 Not
    Modified ),参考 超文本传输协议的实体标记

  20. If-Range 如果该实体未被修改过,则向返回所缺少的那一个或多个部分。否则,返回整个新的实体

  21. If-Unmodified-Since仅当该实体自某个特定时间以来未被修改的情况下,才发送回应。

  22. Max-Forwards 限制该消息可被代理及网关转发的次数。

  23. Origin 发起一个针对跨域资源共享的请求(该请求要求服务器在响应中加入一个 Access-Control-Allow-Origin 的消息头,表示访问控制所允许的来源)。

  24. Pragma 与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生。

  25. Proxy-Authorization 用于向代理进行认证的认证信息。

  26. Range 用于断点续传 bytes=0-5 指定第一个字节的位置和最后一个字节的位置。用于告诉服务器自己想取对象的哪部分。始。

  27. Referer 当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理

  28. TE 浏览器预期接受的传输时的编码方式:可使用回应协议头Transfer-Encoding 中的值(还可以使用"trailers"表示数据传输时的分块方式)用来表示浏览器希望在最后一个大小为0 的块之后还接收到一些额外的字段。

  29. User-Agent User-Agent:Mozilla/…,告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本

  30. Upgrade 要求服务器升级到一个高版本协议。

  31. Via 告诉服务器,这个请求是由哪些代理发出的。

  32. Warning 一个一般性的警告,表示在实体内容体中可能存在错误。

26、http 常用响应头

  1. Cache-Control(对应请求中的Cache-Control)

  2. Content-Type
    Content-Type: text/html;charset=UTF-8 告诉客户端,资源文件的类型,还有字符编码,客户端通过utf-8对资源进行解码,然后对资源进行html解析。通常我们会看到有些网站是乱码的,往往就是服务器端没有返回正确的编码。

  3. Content-Encoding
    Content-Encoding:gzip 告诉客户端,服务端发送的资源是采用gzip编码的,客户端看到这个信息后,应该采用gzip对资源进行解码。

  4. Date
    Date: Tue, 03 Apr 2020 03:52:28 GMT 这个是服务端发送资源时的服务器时间,GMT是格林尼治所在地的标准时间。http协议中发送的时间都是GMT的,这主要是解决在互联网上,不同时区在相互请求资源的时候,时间混乱问题。

  5. Server
    Server:Tengine/1.4.6 这个是服务器和相对应的版本,只是告诉客户端服务器信息。

  6. Transfer-Encoding
    Transfer-Encoding:chunked 这个响应头告诉客户端,服务器发送的资源的方式是分块发送的。一般分块发送的资源都是服务器动态生成的,在发送时还不知道发送资源的大小,所以采用分块发送,每一块都是独立的,独立的块都能标示自己的长度,最后一块是0长度的,当客户端读到这个0长度的块时,就可以确定资源已经传输完了。

  7. Expires
    Expires:Sun, 1 Jan 1994 01:00:00 GMT 这个响应头也是跟缓存有关的,告诉客户端在这个时间前,可以直接访问缓存副本,很显然这个值会存在问题,因为客户端和服务器的时间不一定会都是相同的,如果时间不同就会导致问题。所以这个响应头是没有Cache-Control:max-age=*这个响应头准确的,因为max-age=date中的date是个相对时间,不仅更好理解,也更准确。

  8. Last-Modified
    Last-Modified: Dec, 26 Dec 2019 17:30:00 GMT 所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示)

  9. Connection
    Connection:keep-alive 这个字段作为回应客户端的Connection:keep-alive,告诉客户端服务器的tcp连接也是一个长连接,客户端可以继续使用这个tcp连接发送http请求。

  10. Etag
    ETag: “637060cd8c284d8af7ad3082f209582d” 就是一个对象(比如URL)的标志值,就一个对象而言,比如一个html文件,如果被修改了,其Etag也会别修改,所以,ETag的作用跟Last-Modified的作用差不多,主要供WEB服务器判断一个对象是否改变了。比如前一次请求某个html文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得ETag值发送给WEB服务器,然后WEB服务器会把这个ETag跟该文件的当前ETag进行对比,然后就知道这个文件有没有改变了。

  11. Refresh
    Refresh: 5; url=http://baidu.com 用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。

  12. Access-Control-Allow-Origin
    Access-Control-Allow-Origin: * 号代表所有网站可以跨域资源共享,如果当前字段为那么Access-Control-Allow-Credentials就不能为true
    Access-Control-Allow-Origin: www.baidu.com 指定哪些网站可以跨域资源共享

  13. Access-Control-Allow-Methods
    Access-Control-Allow-Methods:GET,POST,PUT,DELETE 允许哪些方法来访问

  14. Access-Control-Allow-Credentials
    Access-Control-Allow-Credentials: true 是否允许发送cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。如果access-control-allow-origin为*,当前字段就不能为true

  15. Content-Range
    Content-Range: bytes 0-5/7877 指定整个实体中的一部分的插入位置,它也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。

27、 强缓存和协商缓存

缓存类型 获取资源形式 状态码 发送请求到服务器
强缓存 从缓存取 200(from cache) 否,直接从缓存取
协商缓存 从缓存取 304(not modified) 是,通过服务器来告知缓存是否可用

强缓存相关字段有 expires,cache-control。如果 cache-control 与expires 同时存在的话,cache-control 的优先级高于 expires。

协商缓存相关字段有 Last-Modified/If-Modified-Since,Etag/If-None-Match

28、 强缓存、协商缓存什么时候用哪个

强缓存是利用http头中的Expires和Cache-Control两个字段来控制的,用来表示资源的缓存时间。强缓存中,普通刷新会忽略它,但不会清除它,需要强制刷新。浏览器强制刷新,请求会带上Cache-Control:no-cache和Pragma:no-cache

协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问。

普通刷新会启用弱缓存,忽略强缓存。只有在地址栏或收藏夹输入网址、通过链接引用资源等情况下,浏览器才会启用强缓存,这也是为什么有时候我们更新一张图片、一个js文件,页面内容依然是旧的,但是直接浏览器访问那个图片或文件,看到的内容却是新的。

参考:https://segmentfault.com/a/1190000008956069

29、前端web性能优化

  • 降低请求量:合并资源,减少 HTTP 请求数,minify / gzip 压缩,webP,lazyLoad。
  • 加快请求速度:预解析 DNS,减少域名数,并行加载,CDN 分发。
  • 缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存localStorage。
  • 渲染:JS/CSS 优化,加载顺序,服务端渲染,pipeline。

30、 GET 和 POST 的区别

  • get 参数通过 url 传递,post 放在 request body 中。
  • get 请求在 url 中传递的参数是有长度限制的,而 post 没有。
  • get 比 post 更不安全,因为参数直接暴露在 url 中,所以不能用来传递敏感信息。
  • get 请求只能进行 url 编码,而 post 支持多种编码方式
  • get 请求会浏览器主动 cache,而POST不会,除非手动设置。
  • get 请求参数会被完整保留在浏览历史记录里,而 post 中的参数不会被保留。
  • GET 和 POST 本质上就是 TCP 链接,并无差别。但是由于 HTTP 的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
  • GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包。

31、301 和 302 的区别

301 代表永久性转移(Permanently Moved)
302 代表暂时性转移(Temporarily Moved )

参考:https://blog.csdn.net/grandPang/article/details/47448395

301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。

他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。

什么时候进行301或者302跳转呢?

当一个网站或者网页24—48小时内临时移动到一个新的位置,这时候就要进行302跳转

使用301跳转的场景:

1)域名到期不想续费(或者发现了更适合网站的域名),想换个域名。

2)在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。

3)空间服务器不稳定,换空间的时候。

为什么尽量要使用301跳转?

从网站A(网站比较烂)上做了一个302跳转到网站B(搜索排名很靠前),这时候有时搜索引擎会使用网站B的内容,但却收录了网站A的地址,这样在不知不觉间,网站B在为网站A作贡献,网站A的排名就靠前了

301跳转对查找引擎是一种对照驯良的跳转编制,也是查找引擎能够遭遇的跳转编制,它告诉查找引擎,这个地址弃用了,永远转向一个新地址,可以转移新域名的权重。而302重定向很容易被搜索引擎误认为是利用多个域名指向同一网站,那么你的网站就会被封掉,罪名是“利用重复的内容来干扰Google搜索结果的网站排名”。

32、状态码 304 和 200当客户端第一次请求服务器资源,服务器成功返回资源,这时状态码为200。

当客户第一次请求服务器资源,服务器成功返回资源,这时状态码为200。所以,状态码为200的数据包往往包含用户从服务器获取的数据。

每个资源请求完成后,通常会被缓存在客户端,并会记录资源的有效时间和修改时间。当客户再次请求该资源,客户端首先从缓存中查找该资源。如果该资源存在,并且在有效期,则不请求服务器,就不会产生对应的请求数据包。

如果不在有效期,客户端会请求服务器,重新获取。服务器会判断修改时间,如果没有修改过,就会返回状态码304,告诉客户端该资源仍然有效,客户端会直接使用缓存的资源。针对304的响应,渗透人员可以分析对应的请求包,获取资源路径。如果该资源不限制访问,就可以直接请求获取。否则,就需要进行Cookie劫持,进行获取。

33、如何画一个三角形

div {width:0px;height:0px;border-top:10px solid red;border-right:10px solid transparent;border-bottom:10px solid transparent;border-left:10px solid transparent;
}

34、HTML5 新增的元素

  • 为了更好的实践 web 语义化,增加了 header,footer,nav,aside,section 等语义化标签
  • 为了增强表单,为 input 增加了 color,emial,data ,range 等类型
  • 在存储方面,提供了 sessionStorage,localStorage,和离线存储,通过这些存储方式方便数据在客户端的存储和获取
  • 在多媒体方面规定了音频和视频元素audio 和vedio
  • 另外还有地理定位,canvas 画布,拖放,多线程编程的 web worker 和websocket 协议。

35、在地址栏里输入一个 URL,到这个页面呈现出来,中间会发生什么?

  1. 首先在浏览器中输入URL

  2. 查找缓存:浏览器先查看浏览器缓存-系统缓存-路由缓存中是否有该地址页面,如果有则显示页面内容。如果没有则进行下一步。

    • 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
    • 操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统, 获取操作系统的记录(保存最近的DNS查询缓存);
    • 路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
    • ISP缓存:若上述均失败,继续向ISP搜索。
  3. DNS域名解析:浏览器向DNS服务器发起请求,解析该URL中的域名对应的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。

  4. 建立TCP连接:解析出IP地址后,根据IP地址和默认80端口,和服务器建立TCP连接

  5. 发起HTTP请求:浏览器发起读取文件的HTTP请求,,该请求报文作为TCP三次握手的第三次数据发送给服务器

  6. 服务器响应请求并返回结果:服务器对浏览器请求做出响应,并把对应的html文件发送给浏览器

  7. 关闭TCP连接:通过四次挥手释放TCP连接

  8. 浏览器渲染:客户端(浏览器)解析HTML内容并渲染出来,浏览器接收到数据包后的解析流程为:

    • 构建DOM树:词法分析然后解析成DOM树(dom tree),是由dom元素及属性节点组成,树的根是document对象
    • 构建CSS规则树:生成CSS规则树(CSS Rule Tree)
    • 构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树(render tree)
    • 布局(Layout):计算出每个节点在屏幕中的位置
    • 绘制(Painting):即遍历render树,并使用UI后端层绘制每个节点
  9. JS引擎解析过程:调用JS引擎执行JS代码(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)

    • 创建window对象:window对象也叫全局执行环境,当页面产生时就被创建,所有的全局变量和函数都属于window的属性和方法,而DOM Tree也会映射在window的doucment对象上。当关闭网页或者关闭浏览器时,全局执行环境会被销毁。
    • 加载文件:完成js引擎分析它的语法与词法是否合法,如果合法进入预编译
    • 预编译:在预编译的过程中,浏览器会寻找全局变量声明,把它作为window的属性加入到window对象中,并给变量赋值为’undefined’;寻找全局函数声明,把它作为window的方法加入到window对象中,并将函数体赋值给他(匿名函数是不参与预编译的,因为它是变量)。而变量提升作为不合理的地方在ES6中已经解决了,函数提升还存在。
    • 解释执行:执行到变量就赋值,如果变量没有被定义,也就没有被预编译直接赋值,在ES5非严格模式下这个变量会成为window的一个属性,也就是成为全局变量。string、int这样的值就是直接把值放在变量的存储空间里,object对象就是把指针指向变量的存储空间。函数执行,就将函数的环境推入一个环境的栈中,执行完成后再弹出,控制权交还给之前的环境。JS作用域其实就是这样的执行流机制实现的。

36、HTTP2.0 的特性

参考:http://www.javashuo.com/article/p-asqnzngi-mg.html

  1. 二进制分帧

    • 对性能优化的贡献:二进制分帧主要是为下文中的各类特性提供了基础。它能把一个数据划分封装为更小更便捷的数据。首先是在单连接多资源方式中,减小了服务端的连接压力,内存占用更少,连接吞吐量更大。 另外一方面,因为TCP连接的减小而使网络拥塞状态得以改善,同时慢启动时间的减小。使拥塞和丢包恢复的速度更快
  2. 首部压缩
    对性能优化的贡献: 使报头更紧凑,更快速传输,有利于移动网络环境。减小每次通信的数据量,使网络拥塞状态得以改善

  3. 流量控制

    • 流量基于HTTP连接的每一跳进行,而非端到端的控制
    • 流量控制基于窗口更新帧进行,即接收方广播本身准备接收某个数据流的多少字节,以及对整个连接要接收多少个字节。
    • 流量控制有方向性,即接收方可能根据本身的状况为没个流乃至整个连接设置任意窗口大小
    • 流量控制能够由接收方禁用,包括针对个别的流和针对整个连接。
    • 帧的类型决定了流量控制是否适用于帧,目前只有DATA帧服从流量控制,全部其余类型的帧并不会消耗流量控制窗口的空间。这保证了重要的控制帧不会被流量控制阻塞
  4. 多路复用

    • 在HTTP1.1中,浏览器客户端在同一时间,针对同一域名下的请求有必定数量的限制。超过限制数目的请求会被阻塞。而HTTP2.0中的多路复用优化了这一性能。
    • 基于二进制分帧层,HTTP2.0能够在共享TCP连接的基础上同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息自己的语义,交错发出去,在另外一端根据流标识符和首部将他们从新组装起来。
    • 对性能优化的贡献
      • 能够并行交错的发送请求和响应,这些请求和响应之间互不影响
      • 只使用一个连接便可并行发送多个请求和响应
      • 消除没必要要的延迟,从而减小页面加载的时间
      • 没必要再为绕过HTTP1.x限制而多作不少工做
  5. 请求优先级

    • 把HTTP消息分为不少独立帧以后,就能够经过优化这些帧的交错和传输顺序进一步优化性能。
    • 客户端明确指定优先级,服务端能够根据这个优先级做为交互数据的依据,好比客户端优先设置为.css>.js>.jpg。服务端按此顺序返回结果更加有利于高效利用底层链接,提升用户体验。然而,在使用请求优先级时应注意服务端是否支持请求优先级,是否会引发队首阻塞问题,好比高优先级的慢响应请求会阻塞其余资源的交互。
    • 对性能优化的贡献:服务器能够根据流的优先级控制资源分配(CPU、内存、宽带),而在响应数据准备好以后,优先将最高优先级的帧发送给客户端。浏览器能够在发现资源时当即分派请求,指定每一个流的优先级,让服务器决定最优的响应次序。这样请求就不用排队了,既节省了时间,又最大限度的利用了每一个链接。
  6. 服务器推送

    • HTTP2.0新增的一个强大的新功能,就是服务器能够对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确的请求。
    • 对性能优化的贡献:服务端推送是一种在客户端请求以前发送数据的机制。在HTTP2.0中,服务器能够对一个客户端的请求发送多个响应。若是一个请求是由你的主页发送的,服务器可能会响应主页内容、logo以及样式表,由于他知道客户端会用到这些东西。这样不但减轻了数据传送冗余步骤,也加快了页面响应的速度,提升了用户体验

37、cache-control 的值有哪些

cache-control 是一个通用消息头字段被用于 HTTP 请求和响应中,通过指定指令来实现缓存机制,这个缓存指令是单向的,常见的取值有 private、no-cache、max-age、must-revalidate 等,默认为 private。

38、浏览器在生成页面的时候,会生成那两颗树?

构造两棵树,DOM 树和 CSSOM 规则树,
当浏览器接收到服务器相应来的 HTML 文档后,会遍历文档节点,生成DOM树,CSSOM 规则树由浏览器解析 CSS 文件生成。

39、csrf 和 xss 的网络攻击及防范

  • CSRF(Cross Site Request Forgery,跨站请求伪造),字面理解意思就是在别的站点伪造了一个请求。专业术语来说就是在受害者访问一个网站时,其Cookie 还没有过期的情况下,攻击者伪造一个链接地址发送受害者并欺骗让其点击,从而形成CSRF 攻击。
  • XSS, 即为(Cross Site Scripting), 中文名为跨站脚本, 是发生在目标用户的浏览器层面上的,当渲染 DOM 树的过程成发生了不在预期内执行的 JS 代码时,就发生了XSS 攻击。大多数 XSS 攻击的主要方式是嵌入一段远程或者第三方域上的JS 代码。实际上是在目标网站的作用域下执行了这段 JS 代码。

防范:

  • XSS 防御的总体思路是:对输入(和 URL 参数)进行过滤,对输出进行编码。也就是对提交的所有内容进行过滤,对 url 中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行 html 编码,使脚本无法在浏览器中执行。虽然对输入过滤可以被绕过,但是也还是会拦截很大一部分的 XSS 攻击。
  • 防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加token 并验证;在 HTTP 头中自定义属性并验证。

40、知道 304 吗,什么时候用 304?

304:如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304 状态码。

41、cookie 有哪些字段可以设置

  1. Name: Cookie名称,一旦创建不可修改
  2. Value: Cookie值
  3. Domain: Cookie在哪个域是有效的,也就是决定向该域发送请求时是否携带此Cookie,对子域名生效
  4. Path: 可以访问此 cookie 的页面路径。 比如 domain 是 abc.com,path 是/test,那么只有/test 路径下的页面可以读取此 cookie,对子路径生效。
  5. Expires/Max-age: 均为Cookie的有效期,Expires是该Cookie被删除的时间戳,不设置则默认关闭时删除,Max-age是Cookie的有效期,表示多少秒后失效,0立即失效,-1关闭页面时失效。
  6. Size: Cookie的大小
  7. HttpOnly: 值为true或false,设为true时,不允许document.cookie去更改这个值,这个值在document.cookie中也不可见,但请求仍会携带
  8. Secure: Cookie的安全属性,设置为true,则浏览器只会在https和SSL等安全协议中传输此cookie,不会在不安全的http协议中传输
  9. SameSite: 限制第三方cookie,表示Cookie不随着跨域请求发送,减少安全风险
    • Strict: 最为严格,完全禁止第三方cookie,跨站点时任何情况都不发送cookie
    • Lax: 稍稍放宽,大多数情况不发送第三方cookie,但导航到目标网址的get请求除外
    • None: 网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
  10. Priority: 优先级,chrome的提案,定义了三种优先级,Low/Medium/High,cookie数量超出限制时低优先级会被优先清除

42、 cookie 有哪些编码方式?

encodeURI()

43、HTML5 和 CSS3 用的多吗?你了解它们的新属性吗?有在项目中用过吗?

html5:

  1. 标签增删

    • 8 个语义元素 header section footer aside nav main article figure
    • 内容元素 mark 高亮 progress 进度
    • 新的表单控件 calander date time email url search
    • 新的 input 类型 color date datetime datetime-local email
    • 移除过时标签 big font frame frameset
  2. canvas 绘图,支持内联 SVG。支持 MathML
  3. 多媒体 audio video source embed track
  4. 本地离线存储,把需要离线存储在本地的文件列在一个 manifest 配置文件5)web 存储。localStorage、SessionStorage

css3:

  1. CSS3边框如border-radius,box-shadow,border-image;
  2. CSS3背景如background-size,background-origin等;
  3. CSS3文字效果:text-shadow、word-wrap
  4. CSS3 2D,3D 转换如 transform 等;
  5. CSS3 动画如 animation 等
    参考:https://www.cnblogs.com/xkweb/p/5862612.html

二、CSS

1、说一下css盒子模型

标准盒模型中,盒子宽度等于内容区宽度,如下所示

IE盒模型中,盒子宽度等于内容区宽度、内边距和边框三部分的总和,如下所示

可以借助CSS3的box-sizing属性切换盒模型,如下所示

2、画一条 0.5px 的线

  1. 移动端,采用meta viewport的方式
<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/>

这样子就能缩放到原来的0.5倍,如果是1px那么就会变成0.5px。,但这样也意味着UI需要按2倍图的出,整体面面的单位都会放大一倍。

  1. 采用 transform: scale()的方式
transform: scale(0.5,0.5);
  1. 使用boxshadow

    设置box-shadow的第二个参数为0.5px,表示阴影垂直方向的偏移为0.5px

<style>.boxshadow {height: 1px;background: none;box-shadow: 0 0.5px 0 #000;
}</style>
<p>box-shadow: 0 0.5px 0 #000</p><div class="boxshadow"></div>
  1. 采用 border-image的方式
    首先需要自己制作一个0.5像素的线条作为线条背景图片;

  2. 使用background-image结合SVG的方式

    使用svg的line元素画线,stroke表示描边颜色,默认描边宽度stroke-width=“1”,由于svg的描边等属性的1px是物理像素的1px,相当于高清屏的0.5px
    这样在Chrome在能很好的显示,但在firefox挂了,究其原因是因为firefox的background-image如果是svg的话只支持命名的颜色,如"black"、"red"等,如果把上面代码的svg里面的#000改成black的话就可以显示出来,但是这样就很不灵活了。因此,只能把svg转成base64的形式,最终如下:

.hr.svg {background: url("data:image/svg+xml;utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='1px'><line x1='0' y1='0' x2='100%' y2='0' stroke='#000'></line></svg>");//使用base64来使得支持firefoxbackground: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMDAlJyBoZWlnaHQ9JzFweCc+PGxpbmUgeDE9JzAnIHkxPScwJyB4Mj0nMTAwJScgeTI9JzAnIHN0cm9rZT0nIzAwMCc+PC9saW5lPjwvc3ZnPg==");
}

3、link 标签和 import 标签的区别

  • link 属于 html 标签,而@import 是 css 提供的
  • 页面被加载时,link 会同时被加载,而@import 引用的 css 会等到页面加载结束后加载。
  • link 是 html 标签,因此没有兼容性,而@import 只有 IE5 以上才能识别。
  • link 方式样式的权重高于@import 的。

4、css动画transition 和 animation 的区别

Animation 和 transition 大部分属性是相同的,他们都是随时间改变元素的属性值,他们的主要区别是

  • transition 需要触发一个事件才能改变属性,而 animation 不需要触发任何事件的情况下才会随时间改变属性值

  • transition 只有两个状态:开始状态 和 结束状态 。animation 可能是多个状态, 有帧的概念 。

  • animation 控制动效上要比 transition 强,因为它具备一些控制动效的属性,比如“播放次数”、“播放方向”、“播放状态”等。

5、Flex 布局

  • 任何一个容器都可以指定为 Flex 布局
  • 设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效

以下6个属性设置在容器上

  1. flex-direction :决定主轴的方向 ,取值 row | row-reverse | column | column-reverse
  2. flex-wrap : 如果一条轴线排不下,如何换行 ,取值 nowrap | wrap | wrap-reverse
  3. flex-flowflex-directionflex-wrap的简写形式,默认值为row nowrap
  4. justify-content:项目在主轴上的对齐方式,取值 flex-start | flex-end | center | space-between | space-around;
  5. align-items:项目在交叉轴上如何对齐,取值flex-start | flex-end | center | baseline | stretch
  6. align-content:多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用,取值flex-start | flex-end | center | space-between | space-around | stretch

以下6个属性设置在项目上

  1. order:项目的排列顺序。数值越小,排列越靠前,默认为0
  2. flex-grow :项目的放大比例,默认为0,即如果存在剩余空间,也不放大。如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
  3. flex-shrink: 项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小
  4. flex-basis:定义了在分配多余空间之前,项目占据的主轴空间。览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。它可以设为跟width或height属性一样的值
  5. flex:flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选;该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
  6. align-self:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。取值auto | flex-start | flex-end | center | baseline | stretch

6、BFC(块级格式化上下文,用于清除浮动,防止margin 重叠等)

简单的理解:这是一个独立的渲染区域,规定了内部如何布局,并且这个区域的子元素不会影响到外面的元素,其中比较重要的布局规则有内部box 垂直放置

生成BFC的元素

  • 根元素(html)
  • 浮动元素(元素的float值不是none)
  • 绝对定位元素(元素的position为absolute或者fixed)
  • 行内块元素(元素的display为inline-block)
  • 表格单元格(元素的display为table-cell,HTML表格单元格默认为该值,表格标题(元素的display为table-caption,HTML表格标题默认为该值)row,tbody,thead,tfoot的默认属性)或inline-table)
  • overflow计算值(Computed)不为visible的块元素
  • 弹性元素(display为flex或inline-flex元素的直接子元素)
  • 网格元素(display为grid或inline-grid元素的直接子元素)
  • display值为flow-root的元素

7、垂直居中的方法

  1. margin:auto
position: absolute;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
  1. margin 负值法
position: absolute;
top: 50%;
left: 50%;
margin-top: -190px; /*height 的一半*/
margin-left: -240px; /*width 的一半*/

这里也可以将 marin-top 和 margin-left 负值替换成,transform:translateX(-50%)和 transform:translateY(-50%)

  1. table-cell(未脱离文档流的)
    设置父元素的 display:table-cell,并且 vertical-align:middle,这样子元素可以实现垂直居中
  2. flex
    将父元素设置为 display:flex,并且设置 align-items:center;justify-content:center;

8、关于 JS 动画和 css3 动画的差异性

渲染线程分为 main thread (主线程)和 compositor thread(复合线程),如果 css 动画只改变transform和opacity,在Chromium基础上的浏览器中,这时整个 CSS 动画得以在复合线程 完成(而 JS 动画则会在主线程执行,然后触发复合线程进行下一步操作),特别注意的是如果改变transform和opacity是不会 layout(布局) 或者 paint (绘制)的。 如果在CSS动画或JS动画都触发了paint或layout时,需要main thread进行Layer树的重计算,这时CSS动画或JS动画都会阻塞后续操作

区别:
1、js动画的控制能力比css3动画强;
2、js动画的效果比css3动画丰富;
3、js动画大多数情况下没有兼容性问题,而css3动画有兼容性问题;
4、js动画的复杂度高于css3动画。

js动画

优点:

  1. 灵活,js动画控制能力强,可以在动画过程中对动画进行精细控制,开始、暂停、终止、取消都是可以做到的
  2. 动画效果比css3动画丰富,比如曲线运动,冲击闪烁,视差滚动效果,只有js动画才能完成
  3. js动画大多数情况下没有兼容性问题,而css3动画有兼容性问题

缺点:

  1. js动画的复杂度高于css3
  2. js在动画浏览器的主线程中执行,而主线程还有其他javaScript脚本,样式计算、布局、绘制任务等,对其干扰可能出现阻塞从而出现丢帧的情况
  3. js动画往往需要频繁操作DOM的css属性来实现视觉上的动画效果,这个时候浏览器要不停地执行重绘和重排,这对于性能的消耗是很大的,尤其是在分配给浏览器的内存没那么宽裕的移动端

CSS3动画

优点:

  • 在Chromium基础上的浏览器中,CSS动画不触发layout或pain情况下,浏览器可以对动画进行优化。

缺点:

  1. 运行进程控制较弱,css3动画只能在某些场景下控制动画的暂停与继续,不能在特定的位置添加添加回调函数
  2. 代码冗长。想用 CSS 实现稍微复杂一点动画,最后CSS代码都会变得非常笨重

css动画比js动画流畅的前提

  • js在执行一些复杂的任务
  • css动画比较少或者不触发pain和layout,即重绘和重排,例如通过改变如下属性生成的css动画
    • backface-visibility
    • opacity
    • perspective (设置元素视图)
    • perspective-origin
    • transfrom
  • 部分属性能够启动3D加速和GPU硬件加速,例如使用transform的translateZ进行3D变换时
  • 在Chromium基础上的浏览器中,这个貌似是内核做了优化,当css动画知识改变transfrom和opacity时,整个CSS动画得以在compositor thread完成(而JS动画则会在main thread执行),这样css动画渲染不会影响主线程。

9、说一下块元素和行元素

  • 块元素:独占一行,并且有自动填满父元素,可以设置 margin 和pading 以及高度和宽度
  • 行元素:不会独占一行,width 和 height 会失效,并且在垂直方向的padding 和margin会失效。

10、单行、多行元素的文本省略号

单行

white-space: nowrap; /* 文本超过容器最大宽度不换行(若文本自动显示在一行则不需要这个属性) */
overflow: hidden;  /* 本文超出容器最大宽度的部分不显示 */
text-overflow: ellipsis;  /* 文本超出容器最大宽度时显示三个点 */

多行

overflow:hidden;
display:-webkit-box; /* 让容器变成一个弹性伸缩盒子 */
-webkit-line-clamp:2;  /* 最大显示的文本行数 */
-webkit-box-orient:vertical;  /* 设置或检索伸缩盒对象的子元素纵向排列  */

11、visibility:hidden, opacity:0,display:none

  • opacity:0,透明度为0,不会改变页面布局,并且,如果该元素已经绑定一些事件,如 click 事件,那么点击该区域,也能触发点击事件的
  • visibility:hidden,不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见。不能点击,子孙元素继承visibility:hidden样式,可设置子孙样式visibility:visibile覆盖祖先的visibility:hidden样式,可见的子孙元素和它本身都绑定click事件时,点击子孙元素会触发子孙的click事件,也会冒泡到visibility:hidden元素上
  • display:none,会让元素完全从渲染树中消失,渲染的时候不占据任何空间。不能点击,子孙元素不继承该样式,但是由于display:none元素不渲染,所以子孙不可显示

12、双边距重叠问题(外边距折叠)

多个相邻(兄弟或者父子关系)普通流的块元素垂直方向 marigin 会重叠折叠的结果为:

  • 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
  • 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
  • 两个外边距一正一负时,折叠结果是两者的相加的和。

13、 position 属性

  • 固定定位 fixed:
    元素的位置相对于浏览器窗口是固定位置,即使窗口是滚动的它也不会移动。Fixed 定位使元素的位置与文档流无关,因此不占据空间。
  • 相对定位 relative:
    如果对一个元素进行相对定位,它将出现在它所在的位置上。然后,可以通过设置垂直或水平位置,让这个元素“相对于”它的起点进行移动。 在使用相对定位时,无论是否进行移动,元素仍然占据原来的空间。因此,移动元素会导致它覆盖其它框。
  • 绝对定位 absolute:
    绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于。absolute 定位使元素的位置与文档流无关,因此不占据空间。
  • 粘性定位 sticky:
    元素先按照普通文档流定位,然后相对于该元素在流中的 flow root(BFC)和containingblock(最近的块级祖先元素)定位。而后,元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。
  • 默认定位 Static:
    默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者z-index 声明)。
  • inherit: 规定应该从父元素继承 position 属性的值。

14、清除浮动

  • 浮动的设置:css属性float:left/right/none 左浮动/右浮动/不浮动(默认)
  • 浮动的原理:使当前元素脱离普通流,相当于浮动起来一样,浮动的框可以左右移动,直至它的外边缘遇到包含框或者另一个浮动框的边缘
  • 浮动的影响:对附近的元素布局造成改变,使得布局混乱

因为浮动元素脱离了普通流,会出现一种高度坍塌的现象:原来的父容器高度是内部元素撑开的,但是当内部元素浮动后,脱离普通流浮动起来,那父容器的高度就坍塌,变为高度0px。

清除浮动的5种方法

  1. 在浮动元素后使用一个空元素设置 .clear{clear:both;}

  2. 父级div定义overflow:hidden;或 overflow:auto

    • 另外在IE6 中还需要触发 hasLayout ,例如为父元素设置容器宽高或设置 zoom:1
    • 在添加 overflow 属性后,浮动元素又回到了容器层,把容器高度撑起,达到了清理浮动的效果。
  3. 父级div定义height

    • 父级div手动定义height,就解决了父级div无法自动获取到高度的问题,只适合高度固定的布局
  4. 使用邻接元素处理,什么都不做,给浮动元素后面的元素添加clear属性。

  5. 父级div定义伪元素:after和zoom推荐使用这种方法,建议定义公共类,以减少CSS代码

    • 结合:after 伪元素(注意这不是伪类,而是伪元素,代表一个元素之后最近的元素)和IEhack ,可以完美兼容当前主流的各大浏览器,这里的 IEhack 指的是触发hasLayout。 为了IE6和IE7浏览器,要给这个父级div的class添加一条zoom:1;触发haslayout。
.clearfix:after{content: "020"; display: block; height: 0; clear: both; visibility: hidden;  }.clearfix {/* 触发 hasLayout */ zoom: 1; }

15、CSS 选择器有哪些,优先级呢

内联选择器,ID选择器,class选择器,属性选择器,伪类选择器,元素选择器,通配符选择器,继承选择器等

  1. !important 优先级10000
  2. 内联选择器 优先级1000
  3. ID选择器 优先级100
  4. 类别选择器 优先级10
  5. 属性选择器 优先级10
  6. 伪类 优先级10
  7. 元素选择器 优先级1
  8. 通配符选择器 优先级0
  9. 继承选择器 没有优先级

16、CSS3 中对溢出的处理

使用CSS3 text-overflow 属性

17、float 的元素,display 是什么

block

18、隐藏页面中某个元素的方法

display:none; visibility:hidden; opacity: 0; position 移到外部,z-index 涂层遮盖等等

19、 三栏布局的实现方式

三栏布局:两边固定,中间自适应

  1. flex 实现: 两边定宽,中间flex:1;首先绘制左右两栏,再绘制中间一栏,主要内容无法最先加载
  2. 流体布局 float+margin: 两边定宽,中间设置margin为两边定宽的值;项目绘制按照左中右排列
  3. BFC:左右浮动,中间添加overflow:hidden或者display: flex,因为BFC不会和浮动元素重叠的规则,主要内容无法最先加载
  4. position定位:左右绝对定位,中间设置margin为两边定宽的值;主要内容可以优先加载
  5. table布局:父级设置display:table,三个子元素设置 display: table-cell,左右两栏设置宽度,中间无需设置;缺点就是无法设置栏间距
  6. 圣杯布局:中间栏的div要写在最前面, 三栏都使用float:left 进行浮动,左右定宽,中间宽度100%,左栏设置margin-left为-100%,右栏的margin-left为其宽度的负值,这时中间沾满100%,需要父元素设置margin为左右两边的宽度,左右两边再设置为相对相位,就可以把中间的盒子完整显示出来
  7. 双飞翼布局:双飞翼布局前两步和圣杯布局一样,只是处理中间栏部分内容被遮挡的问题解决方案不同,只用在中间盒子内部添加一个div,给这个div设置左右margin,即可来避开左右遮挡
  8. grid布局:父元素设置display:grid,子元素设置 grid-template-columns: 200px auto 200px; 有兼容性问题

20、calc 属性

用户动态计算长度值,任何长度值都可以使用 calc()函数计算,需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px)

21、display:table 和本身的 table 有什么区别

display:table 和本身 table 是相对应的,区别在于,display:table 的css 声明能够让一个html 元素和它的子节点像 table 元素一样,使用基于表格的 css 布局,是我们能够轻松定义一个单元格的边界,背景等样式,而不会产生因为使用了 table 那样的制表标签导致的语义化问题。

目前,在大多数开发环境中,已经基本不用table元素来做网页布局了,取而代之的是div+css,那么为什么不用table系表格元素呢?

  1. 用DIV+CSS编写出来的文件k数比用table写出来的要小,不信你在页面中放1000个table和1000个div比比看哪个文件大
  2. table必须在页面完全加载后才显示,没有加载完毕前,table为一片空白,也就是说,需要页面完毕才显示,而div是逐行显示,不需要页面完全加载完毕,就可以一边加载一边显示
  3. 非表格内容用table来装,不符合标签语义化要求,不利于SEO
  4. table的嵌套性太多,用DIV代码会比较简洁

22、z-index

z-index属性只能在设置了position: relative | absolute | fixed的元素和父元素设置了 display: flex属性的子元素中起作用,在其他元素中是不作用的。

23、如果想要改变一个 DOM 元素的字体颜色,不在它本身上进行操作?

可以更改父元素的 color

24、line-height 和 height 的区别

line-height 一般是指布局里面一段文字上下行之间的高度,是针对字体来设置的,height 一般是指容器的整体高度。

25、设置一个元素的背景颜色,背景颜色会填充哪些区域?

background-color 设置的背景颜色会填充元素的 content、padding、border 区域

26、inline-block、inline 和 block 的区别;为什么 img 是inline 还可以设置宽高

  • Block :是块级元素,能设置宽度,高度,margin/padding 水平垂直方向都有效。
  • Inline:设置 width 和 height 无效,margin 在竖直方向上无效,padding 在水平方向垂直方向都有效
  • Inline-block:能设置宽度高度,margin/padding 水平垂直方向 都有效

img确实是行内元素 但它也是置换元素;置换元素就是浏览器根据元素的标签和属性,来决定元素的具体显示内容。置换元素拥有内在尺寸,内置宽高 他们可以设置width/height属性。他们的性质同设置了display:inline-block的元素一致。

27、了解重绘和重排吗,知道怎么去减少重绘和重排吗,让文档脱离文档流有哪些方法

回流:也叫做重排,当我们对 DOM 的修改引发了 DOM 尺寸的变化时,浏览器需要重新计算元素的几何属性,其他元素的几何属性和位置也会因此受到影响,然后再将计算的结果绘制出来。这个过程就是回流

重绘:改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。这个过程就叫重绘

重绘不一定导致回流,回流一定会导致重绘。

减少重绘和回流的方法

  1. 尽量减少table使用,table属性变化使用会直接导致布局重排或者重绘
  2. 当dom元素position属性为fixed或者absolute, 可以通过css形变触发动画效果,此时是不会触发重排的
  3. 不要把 DOM 节点的属性值放在一个循环里当成循环里的变量
  4. 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document
  5. 可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。

28、两个嵌套的 div,position 都是 absolute,子 div 设置top 属性,那么这个top是相对于父元素的哪个位置定位的

boder的内边缘

29、display

主要取值有 none,block,inline-block,inline,flex 等

/* precomposed values */
display: block;
display: inline;
display: inline-block;
display: flex;
display: inline-flex;
display: grid;
display: inline-grid;
display: flow-root;/* box generation */
display: none;
display: contents;/* two-value syntax */
display: block flow;
display: inline flow;
display: inline flow-root;
display: block flex;
display: inline flex;
display: block grid;
display: inline grid;
display: block flow-root;/* other values */
display: table;
display: table-row; /* all table elements have an equivalent CSS display value */
display: list-item;/* Global values */
display: inherit;
display: initial;
display: revert;
display: revert-layer;
display: unset;

30、css 布局

六种布局方式总结:圣杯布局、双飞翼布局、Flex 布局、绝对定位布局、表格布局、网格布局。

31、css 预处理器有什么

less,sass 等

三、JavaScript

1、get 请求传参长度的误区

误区:我们经常说 get 请求参数的大小存在限制,而 post 请求的参数大小是无限制的。实际上 HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对get 请求参数的限制是来源与浏览器或 web 服务器,浏览器或 web 服务器限制了 url 的长度。为了明确这个概念,我们必须再次强调下面几点:

  • HTTP 协议 未规定 GET 和 POST 的长度限制
  • GET 的最大长度显示是因为 浏览器和 web 服务器限制了 URI 的长度
  • 不同的浏览器和 WEB 服务器,限制的最大长度不一样
  • 要支持 IE,则最大长度为 2083byte,若只支持 Chrome,则最大长度8182byte

2、补充 get 和 post 请求在缓存方面的区别

  • get 请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。
  • post 不同,post 做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。

3、说一下闭包

闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建一个函数,通过内部函数访问外部函数的局部变量。

闭包中外部函数返回内部函数,也可以返回对象中的函数

闭包的优缺点

优点:

  1. 可以有私有变量的存在
  2. 避免全局污染
  3. 防止私有变量被垃圾回收机制所清除

缺点:

  • 会造成内存泄漏

解决方法:

  • 将内层函数返回到全局的变量设为null,这种方法只能清除基本数据类型

4、说一下类的创建和继承

4.1 ES5类的创建和继承

类的创建(es5):new 一个 function,在这个 function 的 prototype 里面增加属性和方法。
// 定义一个动物类
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};

这样就生成了一个 Animal 类,实力化生成对象后,有方法和属性

类的继承

1. 原型链继承: 直接让子类的原型对象指向父类实例。当子类实例找不到对应的属性和方法时,就会往它的原型对象,也就是父类实例上找,从而实现对父类的属性和方法的继承

function Cat(){ }
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name);//cat
console.log(cat.eat('fish')); //cat正在吃:fish
console.log(cat.sleep());//cat正在睡觉!
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true

优点:通过原型链继承的方式,原先存在父类型的实例中的所有属性和方法,现在也能存在于子类型的原型中了
缺点:

  • 由于所有子类实例原型都指向同一个父类实例, 因此对某个子类实例的父类引用类型变量修改会影响所有的子类实例;
  • 在创建子类实例时无法向父类构造传参, 即没有实现super()的功能

2. 构造函数继承: 在子类的构造函数中执行父类的构造函数,并为其绑定子类的this,通过call()函数,改变this指针的指向,让父类的构造函数把成员属性和方法都挂到子类的this上去

function Cat(name){Animal.call(this);this.name = name || 'Tom';
}
// Test Code
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.sleep());//Tom正在睡觉!
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

优点:可以实现多继承,避免实例之间共享一个原型实例,能向父类构造方法传参
缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法。

3. 组合继承 相当于构造函数继承和原型链继承的组合体。通过调用父类构造函数,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
// Test Code
var cat = new Cat();
console.log(cat.name);//Tom
console.log(cat.sleep());//Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

优点:可以继承实例属性/方法,也可以继承原型属性/方法;组合继承拥有上面两种方法的优点。同时还能避免上面两种方法的缺点。
缺点:调用了两次父类构造函数,生成了两份实例

4. 寄生式继承 使用原型式继承可以获得一份目标对象的浅拷贝,然后利用这个浅拷贝的能力再进行增强,添加一些方法,这样的继承方式就叫作寄生式继承。

 let parent5 = {name: "parent5",friends: ["p1", "p2", "p3"],getName: function() {return this.name;}};function clone(original) {let clone = Object.create(original); //用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)clone.getFriends = function() {return this.friends;};return clone;}let person5 = clone(parent5);
​console.log(person5.getName());console.log(person5.getFriends());

优点:解决了组合继承中每次创建子类实例都执行了两次构造函数

缺点:

  • 原型继承存在的缺点他都存在。
  • 使用寄生式继承为对象添加方法,会由于不能做到方法的复用而降低效率,这一点和构造函数模式类似。

5. 寄生组合继承 使用寄生式继承来继承父类的原型,将结果指定给子类型的原型;砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性

function Parent6() {this.name = 'parent6';this.play = [1, 2, 3];}Parent6.prototype.getName = function () {return this.name;}function Child6() {Parent6.call(this);this.friends = 'child6';}function clone (parent, child) {// 这里改用 Object.create 就可以减少组合继承中多进行一次构造的过程child.prototype = Object.create(parent.prototype);child.prototype.constructor = child;}clone(Parent6, Child6);Child6.prototype.getFriends = function () {return this.friends;}let person6 = new Child6();console.log(person6); //{name: 'parent6', play: [1, 2, 3], friends: 'child6'}console.log(person6.getName()); //parent6console.log(person6.getFriends()); //child6

优点:

  • 集寄生式继承和组合式继承的优点与一身,实现基本类型继承的最有效方法。
  • 调用了一次父类
  • Child可以向Parent传参
  • 父类方法可以复用
  • 父类的引用属性不会被共享

4.2 ES6类的创建和继承

类的创建

1. 下面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法

   class Box{//类名首字母必须大写,驼峰式命名a=1;//描述改对象的属性值,ES7支持,不需要let或者varconstructor(a,b){// 构造函数console.log(a+b);//8}play(){console.log(this===b)//this 就是通过构造函数实例化对象b,谁调用该方法,this就是谁}}let b=new Box(5,3)  //实例化,当实例化时执行构造函数constructorb.play()console.log(b.constructor === Box)//true//对象的构造函数就是当前的类名console.log(b.constructor === Box.prototype.constructor)//true//b是Box类的实例,它的constructor方法就是Box类原型的constructor方法
  • 类名首字母必须大写,驼峰式命名
  • 如果不继承任何类别,意味着自动继承Object,Object就是js所有类别的基类
  • 对象的构造函数就是当前的类名 ,构造函数是通过该类创建对象的唯一入口函数
  • 如果不写constructor构造函数,类别会自动添加这个函数默认没有内容或者执行超类的构造函数
  • 在其他语言中类名和构造函数名称一样,因为这个类需要实例化对象 ,必须先执行构造函数,有些语言的构造函数可以有多个
  • 原生js构造函数只能有一个,并且所有类的构造函数写为construstor函数,这个构造函数实际就是当前的类名

2. 因为js中构造函数就是类名,因此我们可以根据对象的构造函数是否是某个类名来判断它是否属于该类


//通过实例化创建的对象就是一个类,可以根据构造函数判断是否属于该类var arr=new Array(1,2,3);console.log(arr.constructor.name);//Array//单独打印constrctor是一个函数//构造函数有一个name属性就是这个类的类名console.log(arr.constructor===Array);//truevar date=new Date();console.log(date.constructor===Date);//truevar reg=/a/g;console.log(reg.constructor===RegExp);//truevar div=document.createElement("div");console.log(div.constructor===HTMLDivElement);//true

3. 类中除了函数中的局部变量就是类中的属性,类中的this就是实例化对象

//以下代码只为解释定义一个人类的类,并且去如何使用它,中文编程万万不可以class man{eyes=2;mouse=1;ear=2;hands=2;foots=2;name;//创建了一个man的类,有以上属性constructor(_name){this.name=_name;}walk(){//man的类有walk() run()  eat() fire()的方法console.log(this.name+"走")}run(){console.log(this.name+"跑")}eat(){console.log(this.name+"吃")}fire(){console.log(this.name+"生火")}}var xiaoming=new man("小明");//创建一个xioaming的实例化对象,具备这个man的类的所有方法和属性,可以直接使用xiaoming.eat();xiaoming.run();var xiaohua=new man("小花");//创建了一个xioahua的实例化对象xiaohua.run();xiaohua.fire();
  1. 通过构造函数实例化的对象,就是这个类的实例对象(比如上述代码xiaohua就是通过构造函数实例化的对象,它就是这个类的实例对象)
  2. 因此这个实例对象就具备了类所有属性和方法,比如上述代码xiaohua就具备man这个类的所有属性和方法
  3. 这个实例对象就可以调用他自身的方法和属性了
  4. 因为构造函数默认生成实例化对象,因此不能在构造函数中使用return 返回其他内容,构造函数不允许写return
  5. 谁调用方法,在类的函数中this就是那个实例对象
类的继承

Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

比如,要继承Parent类,只需要使用extends就可以继承过来Parent的属性和方法了,继承父类后,必须在构造函数中使用super()调用超类的构造函数,超类的是什么,这个就执行的是什么;需要注意的是这里的super就可以理解为调用父类的constructor ,所以里面会传一些和父类相同的参数,而且必须写在最前面

ES6 的继承必须先调用super(),这样会生成一个继承父类的this对象,没有这一步就无法继承父类。这意味着新建子类实例时,父类的构造函数必定会先运行一次

class Child extends Parent{constructor(r){// 继承父类后,必须在构造函数中调用超类的构造函数super();//超类的构造函数,超类是什么,这个就是什么//超类的构造函数如果有参数的,在这里子类中必须传入这个需要参数}}

具体可查看该篇文章https://blog.csdn.net/weixin_44157964/article/details/103933204

5、如何解决异步回调地狱

promise、generator、async/await

6、 说说前端中的事件流

HTML 中与 javascript 交互是通过事件驱动来实现的,例如鼠标点击事件onclick、页面的滚动事件 onscroll 等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念

什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2 级事件流包括下面几个阶段

  • 事件捕获阶段:事件从Document节点自上而下向目标节点传播的阶段
  • 处于目标阶段:真正的目标节点正在处理事件的阶段
  • 事件冒泡阶段:事件从目标节点自下而上向Document节点传播的阶段

什么是冒泡?
冒泡是从下往上执行的,比如有个子事件和父事件,点击子事件后触发父事件,浏览器是默认事件冒泡的

事件委托
就是不在事件当前的dom上进行事件,而是在父级进行事件监听,通过事件冒泡来处罚子事件
最常见的就是往ul 上绑定事件来触发 li

addEventListener:addEventListener 是 DOM2 级事件新增的指定事件处理程序的操作,这个方法接收 3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是 true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

IE 只支持事件冒泡

7、如何让事件先冒泡后捕获

根据w3c标准,应先捕获再冒泡。若要实现先冒泡后捕获,给一个元素绑定两个addEventListener,其中一个第三个参数设置为false(即冒泡),另一个第三个参数设置为true(即捕获),调整它们的代码顺序,将设置为false的监听事件放在设置为true的监听事件前面即可。

还有一种,在执行捕获时,设置setTimeOut(方法名,0),把它放到下一个宏任务

8、说一下事件委托

事件委托指的是,不在事件的发生地(直接 dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素 DOM 的类型,来做出不同的响应。

举例:最经典的就是 ul 和 li 标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在 li 标签上直接添加,而是在 ul 父元素上添加。

好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。

9、说一下图片的懒加载和预加载

(1) 懒加载

懒加载:图片的懒加载指的是在长网页中延迟加载图像,是一种很好的优化网页性能的方式。用户滚动到他们之前,可视区域之外的图像是不会加载的。在某种情况下,他还可以帮助减少服务器负载,常适使图片很多,页面很长的电商网站场景中。

为什么要使用懒加载?

  • 可以提升用户体验:我们可以想一下,当用户打开手机淘宝的话,如果页面上全部的图片都需要加载,由于图片
    数量巨大,等待的时间就很长,用户体验就很不好。
  • 减少无用的资源加载:如果用户都没有去查看相应的内容,而我们却需要加载,此时就会增加浏览器的负担。
  • 防止并发资源过多导致阻塞js的加载。

懒加载实现原理

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

(2) 预加载

预加载就是将所需的资源提前加载到本地,这样当用户使用到该资源时,就会自动从缓存中取出。

预加载实现方法

  1. 用html标签
<img src="http://pic26.nipic.com/20121213/6168183 0044449030002.jpg" style="display:none"/>

这样当我们进行加载页面时,也会加载src中的图片资源,此时该图片就会缓存到本地,当我们使用到该图片
时,就会自动读取缓存中的内容。

  1. 使用Image对象,在js解析的时候加载
<script src='./myPreload.js'></script>//myPreload.js文件
var image = new Image()
image.src="http://pic26.nipic.com/20121213/6168183 004444903000 2.jpg"
  1. 使用XMLHTTPRequest对象
    这里我是这样理解的,因为XMLHTTPRequest创建的是异步ajax请求对象,当我们加载完其他内容时,此时我们
    可以使用ajax进行加载资源,此时并不会对页面产生不好的效果。此时当我们加载完毕后,在后面如果我们使用
    到该资源时,就会从缓存中读取出来,加载就会很快。

两种技术的本质:

  • 两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。
  • 懒加载对服务器有一定的缓解压力作用,预加载则会增加服务器压力

参考https://blog.csdn.net/weixin_47450807/article/details/123376938

10、常用的鼠标事件有哪些,mouseover 和 mouseenter 的区别

常用的鼠标事件分为三部分: 鼠标点击事件、鼠标经过事件、鼠标移动事件

鼠标点击事件
鼠标点击事件包括 click(单击)dblclick(双击)mousedown(按下)mouseup(松开)四个;其中 click 事件类型比较常用,而mousedownmouseup 事件类型多用在鼠标拖放、拉伸操作中

鼠标经过事件
mouseover:无论论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件;有一个重复触发,冒泡的过程
mouseenter:只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件;不会冒泡

mouseout:不论鼠标指针离开被选元素还是任何子元素,都会触发 mouseout 事件;有一个重复触发,冒泡的过程
mouseleave:只有在鼠标指针离开被选元素时,才会触发 mouseleave 事件;不会冒泡

鼠标移动事件
mousemove 事件类型是一个实时响应的事件,当鼠标指针的位置发生变化时(至少移动一个像素),就会触发 mousemove 事件。该事件响应的灵敏度主要参考鼠标指针移动速度的快慢以及浏览器跟踪更新的速度

11、JS 的 new 操作符做了哪些事情

  1. 创建一个新对象
  2. 将这个新对象的原型指向构造函数的prototype
  3. 执行构造函数,将this指向新创建的对象
  4. 返回新创建的对象

12、改变函数内部 this 指针的指向函数(bind,apply,call 的区别)

通过 apply 和 call 改变函数的 this 指向,他们两个函数的第一个参数都是一样的表示要改变指向的那个对象,第二个参数,apply 是数组,而 call 则是arg1,arg2…这种形式。 call和apply都会会立即执行该函数

通过 bind 改变 this 作用域会返回一个新的函数,这个函数不会马上执行。需要再调用一次

如果使用call、apply、bind时,第一个参数是null,就意味着将函数中this重定向到window

只有apply的参数是array

13、JS 的各种位置,比如 clientHeight,scrollHeight,offsetHeight ,以及scrollTop, offsetTop,clientTop 的区别?

  • clientHeight:表示的是可视区域的高度,不包含 border 和滚动条
  • offsetHeight:表示可视区域的高度,包含了 border 和滚动条
  • scrollHeight:表示了所有区域的高度,包含了因为滚动被隐藏的部分
  • clientTop:表示边框 border 的厚度,在未指定的情况下一般为 0
  • scrollTop:滚动后被隐藏的高度,获取对象相对于由 offsetParent 属性指定的父坐标(css
    定位的元素或 body 元素)距离顶端的高度

14、JS 拖拽功能的实现

如果要设置物体拖拽,那么必须使用三个事件,并且这三个事件的使用顺序不能颠倒。

  1. onmousedown:鼠标按下事件
  2. onmousemove:鼠标移动事件
  3. onmouseup:鼠标抬起事件

拖拽的基本原理就是根据鼠标的移动来移动被拖拽的元素。鼠标的移动也就是x、y坐标的变化;元素的移动就是style.position的top和left的改变。当然,并不是任何时候移动鼠标都要造成元素的移动,而应该判断鼠标左键的状态是否为按下状态,是否是在可拖拽的元素上按下的。

也可以通过 html5 的拖放(Drag 和 drop)来实现

15、JS异步加载

15.1 为什么要JS异步加载?

因为同步加载存在问题!
JS在默认情况下是以同步模式(又称阻塞模式)加载的,这里“加载”的意思是“解释、执行”。在最新版本的浏览器中,浏览器对于代码请求的资源都是瀑布式的加载,而不是阻塞式的,但是JS的执行总是阻塞的。这会引起什么问题呢?如果在页面中加载一些JS,但其中某个请求迟迟得不到响应,位于此JS后面的JS将无法执行,同时页面渲染也不能继续,用户看到的就是白屏

如果js在<head>标签中,如果JS迟迟无法加载,于是阻塞了后面代码的执行,页面得不到渲染
如果把JS代码放到</body>标签之前(这也是所提倡的页面结构),页面瞬间被渲染,问题似乎解决了,可是…如果我们在引用js代码的后面再写一段js代码,如果上个js请求阻塞了,后面的代码也不会加载,所以问题依然存在:改变JS的加载位置只能改变页面的渲染,JS还是会阻塞。

15.2 异步加载 JS 的方法

  1. defer

    • 等dom文档全部解析完(dom树生成)才会被执行。
  2. async
    • async是HTML5的新属性,该属性规定一旦脚本可用,则会异步执行(一旦下载完毕就会立刻执行)。
    • async属性仅适用于外部脚本(只有在使用src属性时)

15.3 async和defer看起来差不多呀?而且经常一起出现!来辨析一下:

  • 如果没有async和defer属性,那么浏览器会立即执行当前的JS脚本,阻塞后面的脚本;
  • 如果有async属性,加载和渲染后续文档的过程和当前JS的加载与执行并行进行(异步),它是乱序执行的,不管你声明的顺序如何,只要它加载完了就会执行
  • 如果有defer属性,加载后续文档元素的过程和JS的加载是并行进行(异步)的,但是JS的执行在所有元素解析完成之后进行,而且它是按照加载顺序执行脚本的

15、Ajax 解决浏览器缓存问题

  1. ajax 发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")
  2. ajax 发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")
  3. URL 后面加上一个随机数: "fresh=" + Math.random()
  4. URL 后面加上时间搓:"nowtime=" + new Date().getTime()
  5. 如果是使用 jQuery,直接这样就可以了 $.ajaxSetup({cache:false})。

16、JS 的节流和防抖

16.1 防抖和节流

  • 防抖是将多次执行变为最后一次执行
  • 节流是将多次执行变为每隔一段时间执行

16.2 防抖和节流的场景

防抖的应用场景很多:

  • 输入框中频繁的输入内容,搜索或者提交信息;
  • 频繁的点击按钮,触发某个事件;
  • 监听浏览器滚动事件,完成某些特定操作;
  • 用户缩放浏览器的resize事件;
    总之,密集的事件触发,我们只希望触发比较靠后发生的事件,就可以使用防抖函数;

节流的应用场景:

  • 监听页面的滚动事件;
  • 鼠标移动事件;
  • 用户频繁点击按钮操作;
  • 游戏中的一些设计;

总之,依然是密集的事件触发,但是这次密集事件触发的过程,不会等待最后一次才进行函数调用,而是会按照一定的频率进行调用

16.3 防抖和节流的实现

  1. lodash、underscore第三方库来实现
  2. 防抖实现
 // 通过闭包实现防抖function debounce(fn, delay) {let timer = null;return function () {if (timer !== null) {clearTimeout(timer);}timer = setTimeout(() => {// 箭头函数没有自己的this,改变指向,使其指向input。同时执行fn函数fn.call(this);}, delay);};}
  • 第一次点击了输入框,输入内容后,开启定时器,timer会得到一个值。(这个值代表着等待队列);
  • 第二次输入内容时,会进入if判断(已经有值,不为null)。执行清除定时器。重新生成一个定时器,timer得到一个 新- 的值;
  • 如果在3秒内,不停的输入内容,则会不停地触发事件——清除上一个定时器,开启新的定时器;
  • 直到最后一次输入结束,最后一个定时器等待3秒后,输出结果。

可以看出,防抖的关键点在于:利用闭包,在返回的函数体里,通过不断开启和清除定时器,在限定时间内不断点击,仍然只执行最后一次

  1. 节流实现
 function throttle(fn, wait) {// 获取初始时间let start = 0;return function () {let now = new Date().getTime();// 判断前后时间戳的差值if (now - start < wait) return;fn();// 重新设置初始时间start = now;};}
  • 间隔时间 wait
  • 初始时间 start-time
  • 最新时间 new-time (事件被触发时计算)
  • 当2者时间差 < wait , 不能执行事件函数
  • 当2者时间差 > = wait , 执行操作

17、JS 中的垃圾回收机制

必要性:由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript 程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript 的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。

这段话解释了为什么需要系统需要垃圾回收,JS 不像 C/C++,他有自己的一套垃圾回收机制(Garbage Collection)。JavaScript 的解释器可以检测到何时程序不再使用一个对象了,当他确定了一个对象是无用的时候,他就知道不再需要这个对象,可以把它所占用的内存释放掉了

垃圾回收常用的方法:标记清除、计数引用

  • 标记清除

    • 标记阶段:给所有的活动对象打上标记。
    • 清除阶段:回收没有标记的对象。

    缺点:碎片化。经过多轮空间分配和垃圾回收后,堆从一整片完整的空间被划分为了很多不连续的碎片,这就导致另外一个问题:分配速度受限。因为每次重新分配空间时,都要遍历所有空闲链表,去寻找足够大的分块,最坏的情况下,每次进行分配都要遍历整个空闲链表。
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 计数引用
    记录每个值的被引用的次数,当它被初始化,并被赋值给一个变量,引用为 1;如果另外一个变量引用了它,引用加 1;如果一个变量不再引用它,引用减 1。当一个值的引用数变为 0,那就说明它再没法被访问了,因此它成为垃圾,可以放心回收

    缺点:无法回收循环引用的对象,造成内存泄漏

function problem() {let objectA = new Object();let objectB = new Object();objectA.someOtherObject = objectB;objectB.anotherObject = objectA;
}

在上面这个例子中,objectA 和 objectB 通过各自的属性相互引用,于是它们的引用数都是 2。函数运行结束,objectA 和 objectB 的引用次数各自减 1,但因为它们还引用着彼此,所以它们的引用次数永远不会置为 0,也就无法被回收

还有一些别的GC算法:复制算法、标记 - 整理算法、分代式垃圾回收、增量式垃圾回收 具体参考https://www.jianshu.com/p/20364ba1d7a6

18、eval

它的功能是将对应的字符串解析成 JS 并执行,如果传入的参数不是字符串,它会原封不动地将其返回

应该避免使用eval,因为非常消耗性能(2次,一次解析成 JS,一次执行)

eval缺点:

  • 降低性能:网上一些文章甚至说 eval() 会拖慢性能 10 倍,倒没有10倍这么夸张
  • 安全问题:因为它的动态执行特性,给被求值的字符串赋予了太大的权力,于是大家担心可能因此导致 XSS 等攻击。
  • 调试困难:eval 就像一个黑盒,其执行的代码很难进行断点调试。

19、如何理解前端模块化

前端模块化就是复杂的文件编程一个一个独立的模块,比如 JS 文件等等,分成独立的模块有利于重用(复用性)和维护(版本迭代),这样会引来模块之间相互依赖的问题,所以有了 commonJS 规范,AMD,CMD 规范等等,以及用于 JS 打包(编译等处理)的工具 webpack

20、说一下 CommonJS、AMD 和 CMD、ES6模块化


分割线 :下面是待更新的题

对象深度克隆的简单实现… 67 实现一个 once 函数,传入函数参数只执行一次…67 将原生的 ajax 封装成 promise… 67 JS 监听对象属性的改变…68 如何实现一个私有变量,用 getName 方法可以访问,不能直接访问…68 =、以及 Object.is 的区别… 69 setTimeout、setInterval 和 requestAnimationFrame 之间的区别…69 实现一个两列等高布局,讲讲思路… 70 自己实现一个 bind 函数… 70 用 setTimeout 来实现 setInterval… 70 JS 怎么控制一次加载一张图片,加载完后再加载下一张… 71 代码的执行顺序… 72 如何实现 sleep 的效果(es5 或者 es6)… 72 简单的实现一个 promise…73 Function.proto(getPrototypeOf)是什么?…73 实现 JS 中所有对象的深度克隆(包装对象,Date 对象,正则对象)…74 简单实现 Node 的 Events 模块… 76 箭头函数中 this 指向举例… 77 JS 判断类型…77 数组常用方法… 77 数组去重…78 闭包 有什么用… 78 事件代理在捕获阶段的实际应用… 78 去除字符串首尾空格… 78 性能优化…79 来讲讲 JS 的闭包吧…79 能来讲讲 JS 的语言特性吗…79 如何判断一个数组(讲到 typeof 差点掉坑里)… 80 你说到 typeof,能不能加一个限制条件达到判断条件… 80 JS 实现跨域…80 JS 基本数据类型…80 JS 深度拷贝一个元素的具体实现…80 之前说了 ES6set 可以数组去重,是否还有数组去重的方法…81 重排和重绘,讲讲看… 81 JS 的全排列…81 跨域的原理… 82 不同数据类型的值的比较,是怎么转换的,有什么规则…82 null == undefined 为什么…82 this 的指向 哪几种…83 暂停死区…83 AngularJS 双向绑定原理… 83 写一个深度拷贝… 84 简历中提到了 requestAnimationFrame,请问是怎么使用的…85 有一个游戏叫做 Flappy Bird,就是一只小鸟在飞,前面是无尽的沙漠,上下不断有钢管生成,你要躲避钢管。然后小明在玩这个游戏时候老是卡顿甚至崩溃,说出原因(3-5 个)以及解决办法(3-5 个)… 85 编写代码,满足以下条件: (1)Hero(“37er”);执行结果为Hi! This is 37er
( 2) Hero(“37er”).kill(1).recover(30); 执 行 结 果 为 Hi! This is 37er Kill 1 bug
Recover 30 bloods(3)Hero(“37er”).sleep(10).kill(2)执行结果为Hi! This is 37er //
等待 10s 后 Kill 2 bugs //注意为 bugs (双斜线后的为提示信息,不需要打印)85
 什么是按需加载… 86 说一下什么是 virtual dom… 86 webpack 用来干什么的…86 ant-design 优点和缺点… 87 JS 中继承实现的几种方式,…87写一个函数,第一秒打印 1,第二秒打印 2…87 Vue 的生命周期…88 简单介绍一下 symbol… 88 什么是事件监听… 89 介绍一下 promise,及其底层如何实现…89 说说 C++,Java,JavaScript 这三种语言的区别… 90 JS 原型链,原型链的顶端是什么?Object 的原型是什么?Object 的原型的原型是什么?在数组原型链上实现删除数组重复数据的方法…91 什么是 js 的闭包?有什么作用,用闭包写个单例模式… 95 promise+Generator+Async 的使用… 95 事件委托以及冒泡原理。… 99 写个函数,可以转化下划线命名到驼峰命名…99 深浅拷贝的区别和实现… 100 JS 中 string 的 startwith 和 indexof 两种方法的区别… 101 JS 字符串转数字的方法…101 let const var 的区别 ,什么是块级作用域,如何用ES5 的方法实现块级作用域(立即执行函数),ES6 呢…102 ES6 箭头函数的特性…102 setTimeout 和 Promise 的执行顺序… 102 有了解过事件模型吗,DOM0 级和 DOM2 级有什么区别,DOM的分级是什么…103 平时是怎么调试 JS 的…103 JS 的基本数据类型有哪些,基本数据类型和引用数据类型的区别,NaN是什么的缩写,JS 的作用域类型,undefined==null 返回的结果是什么,undefined与 null 的区别在哪,写一个函数判断变量类型…103 setTimeout(fn,100);100 毫秒是如何权衡的… 105 JS 的垃圾回收机制…105 写一个 newBind 函数,完成 bind 的功能。… 105 怎么获得对象上的属性:比如说通过 Object.key()…106 简单讲一讲 ES6 的一些新特性…106 call 和 apply 是用来做什么?…106 了解事件代理吗,这样做有什么好处…107 如何写一个继承?… 107 给 出 以 下 代 码 , 输 出 的 结 果 是 什 么 ? 原 因?for(var i=0;i<5;i++)
{ setTimeout(function(){ console.log(i); },1000); } console.log(i)… 108 给两个构造函数 A 和 B,如何实现 A 继承 B?…108 问能不能正常打印索引… 109 如果已经有三个 promise,A、B 和 C,想串行执行,该怎么写?…109 知道 private 和 public 吗… 109 基础的 js…109 async 和 await 具体该怎么用?… 110 知道哪些 ES6,ES7 的语法… 110 promise 和 await/async 的关系…110 JS 的数据类型…110JS 加载过程阻塞,解决方法。…110 JS 对象类型,基本对象类型以及引用对象类型的区别… 110 JavaScript 中的轮播实现原理?假如一个页面上有两个轮播,你会怎么实现?…111 怎么实现一个计算一年中有多少周?…111 面向对象的继承方式… 111 JS 的数据类型…112 引用类型常见的对象… 112 es6 的常用… 113 class…113 口述数组去重… 113 继承…113 call 和 apply 的区别…114 es6 的常用特性… 115 箭头函数和 function 有什么区别… 115 new 操作符原理… 115 bind,apply,call…115 bind 和 apply 的区别…115 数组的去重… 115 闭包…116 promise 实现… 116 assign 的深拷贝…117 说 promise,没有 promise 怎么办… 118 事件委托…119 箭头函数和 function 的区别… 119 arguments… 119 箭头函数获取 arguments… 119 Promise…119 事件代理…120 Eventloop…1202 | 前端核心… 1202.1| 服务端编程… 120 JSONP 的缺点… 120 跨域(jsonp,ajax)… 120 如何实现跨域… 121 dom 是什么,你的理解?…121 关于 dom 的 api 有什么…1212.2 | Ajax… 121 ajax 返回的状态…121 实现一个 Ajax… 122 如何实现 ajax 请求,假如我有多个请求,我需要让这些ajax 请求按照某种顺序一次执行,有什么办法呢?如何处理 ajax 跨域… 122 写出原生 Ajax… 124 如何实现一个 ajax 请求?如果我想发出两个有顺序的ajax 需要怎么做?124
 Fetch 和 Ajax 比有什么优缺点?…125 原生 JS 的 ajax… 1252.3 | 移动 web 开发… 125 知道 PWA 吗…125 移动布局方案… 125 Rem, Em…126 flex 布局及优缺点…127 Rem 布局及其优缺点…128 百分比布局… 129 移动端适配 1px 的问题…130 移动端性能优化相关经验… 131 toB 和 toC 项目的区别…132 移动端兼容性… 132 小程序…133 2X 图 3X 图适配… 133 图片在安卓上,有些设备模糊问题… 134 固定定位布局键盘挡住输入框内容… 134 click 的 300ms 延迟问题和点击穿透问题…134 phone 及 ipad 下输入框默认内阴影…135 防止手机中页面放大和缩小… 135 px、em、rem、%、vw、vh、vm 这些单位的区别…135 移动端适配- dpr 浅析…136 移动端扩展点击区域… 136 上下拉动滚动条时卡顿、慢… 136 长时间按住页面出现闪退… 136 ios 和 android 下触摸元素时出现半透明灰色遮罩… 136 active 兼容处理 即 伪类:active 失效… 137 webkit mask 兼容处理…137 transiton 闪屏…138 圆角 bug…1383 | 前端进阶… 1383.1 | 前端工程化… 138 Babel 的原理是什么?.. 138 如何写一个 babel 插件?..139 你的 git 工作流是怎样的?.. 143 rebase 与 merge 的区别?..148 git reset、git revert 和 git checkout 有什么区别… 149 webpack 和 gulp 区别(模块化与流的区别)… 1503.2 | Vue 框架… 151 有使用过 Vue 吗?说说你对 Vue 的理解… 151 说说 Vue 的优缺点…151Vue 和 React 有什么不同?使用场景分别是什么?… 151 什么是虚拟 DOM?…152 请描述下 vue 的生命周期是什么?…152 vue 如何监听键盘事件?…155 watch 怎么深度监听对象变化… 156 删除数组用 delete 和 Vue.delete 有什么区别?… 156 watch 和计算属性有什么区别?… 156 Vue 双向绑定原理…157 v-model 是什么?有什么用呢?…157 axios 是什么?怎样使用它?怎么解决跨域的问题?…157 在 vue 项目中如何引入第三方库(比如 jQuery)?有哪些方法可以做到?157
 说说 Vue React angularjs jquery 的区别… 157 Vue3.0 里为什么要用 Proxy API 替代 defineProperty API?…158 Vue3.0 编译做了哪些优化?…158 Vue3.0 新特性 —— Composition API 与 React.js 中Hooks 的异同点…159 Vue3.0 是如何变得更快的?(底层,源码)… 161 vue 要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?…162 vue 在 created 和 mounted 这两个生命周期中请求数据有什么区别呢?162 说说你对 proxy 的理解…1623.3 | React 框架… 162 angularJs 和 React 区别… 162 redux 中间件…163 redux 有什么缺点…163 React 组件的划分业务组件技术组件?…163 React 生命周期函数… 163 React 性能优化是哪个周期函数?…164 为什么虚拟 dom 会提高性能?..164 diff 算法?.. 165 React 性能优化方案… 165 简述 flux 思想… 165 React 项目用过什么脚手架?Mern? Yeoman?..165 你了解 React 吗?… 166 React 解决了什么问题?… 166 React 的协议?… 166 了解 shouldComponentUpdate 吗?…166 React 的工作原理?… 166 使用 React 有何优点?… 166 展示组件(Presentational component)和容器组件(Container component)之间有何不同?…167 类组件(Class component)和函数式组件(Functional component)之间有何不同?…167 (组件的)状态(state)和属性(props)之间有何不同?… 167 应该在 React 组件的何处发起 Ajax 请求?… 168 在 React 中,refs 的作用是什么?… 168 何为高阶组件(higher order component)?…168 使用箭头函数(arrow functions)的优点是什么?…168 为什么建议传递给 setState 的参数是一个 callback 而不是一个对象?168
 除了在构造函数中绑定 this,还有其它方式吗?… 169 怎么阻止组件的渲染?… 169 当渲染一个列表时,何为 key?设置 key 的目的是什么?…169 何为 JSX ?… 1693.4 | Angular 框架…170 Angular 中组件之间通信的方式… 170 Angualr 的八大组成部分并简单描述… 170 Angular 中常见的生命周期的钩子函数?.. 170 Angular 中路由的工作原理…171 解释 rjx 在 Angular 中的使用场景… 171

前端最全面试题整理(持续更新)相关推荐

  1. 前端综合面试题一(持续更新)

    Map和Object的区别 es6提供了一个Map类,这是新增的一个数据结构,用起来有点像Object 区别: Object本质上是哈希结构的键值对的集合,它只能用字符串.数字或者Symbol等简单数 ...

  2. 前端经典面试题(持续更新中)

    前言 写本章的初衷是因为目前网上的面试题层出不穷,各种类型的问题都有,不是很符合本公司的项目要求以及就面试者的水品也是层次不齐,所以很难有一个通用性面试题目. 本文章将根据笔者作为面试官以及面试者的一 ...

  3. 2020年 30K的前端架构面试题总结(持续更新)

    vue部分 vue父子组件通信 props,$ emit , vuex , provide/inject , $ attrs/$ listeners,$root , $parent, $refs, e ...

  4. 最新前端开发面试笔试题及答案---图片(面试题系列持续更新中)(4)

    推荐文章: VUE之VUEX常见面试题大全汇总--史上最全[vuex面试题] 前端面试题之HTML+CSS(持续更新)_勤动手多动脑少说多做厚积薄发-CSDN博客1.行内元素和块级元素?img算什么? ...

  5. 最新前端开发面试笔试题及答案---图片(面试题系列持续更新中)(8)

    推荐文章: VUE之VUEX常见面试题大全汇总--史上最全[vuex面试题] 前端面试题之HTML+CSS(持续更新)_勤动手多动脑少说多做厚积薄发-CSDN博客1.行内元素和块级元素?img算什么? ...

  6. 最新前端开发面试笔试题及答案---图片(面试题系列持续更新中)(3)

    推荐文章: VUE之VUEX常见面试题大全汇总--史上最全[vuex面试题] 前端面试题之HTML+CSS(持续更新)_勤动手多动脑少说多做厚积薄发-CSDN博客1.行内元素和块级元素?img算什么? ...

  7. 最新前端开发面试笔试题及答案---图片(面试题系列持续更新中)(1)

    推荐文章: VUE之VUEX常见面试题大全汇总--史上最全[vuex面试题] 前端面试题之HTML+CSS(持续更新)_勤动手多动脑少说多做厚积薄发-CSDN博客1.行内元素和块级元素?img算什么? ...

  8. Java自学视频整理(持续更新中...)

    1.Java基础视频 <张孝祥JAVA视频教程>完整版[RMVB](东西网) 历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播客) 张孝祥2010年贺岁视频:Java高新技术 ...

  9. 面试1:Java、微服务、架构常见面试题(持续更新中)

    Java.微服务.架构常见面试题(持续更新中) 文章目录 Java.微服务.架构常见面试题(持续更新中) ==**Java**== 1.Java概述 (1)JVM.JRE和JDK (2)Java特点 ...

  10. 面试题(持续更新……)

    前端面试题(持续更新) 1.说说你对react的理解?有哪些特性? 特性 2.说说Real DOM和Virtual DOM的区别?优缺点? 3.说说React生命周期有哪些不同的阶段?每个阶段对应的方 ...

最新文章

  1. wpf开发仿真3d软件_web 3d 与仿真
  2. 功率谱 幅值谱_疲劳损伤谱(FDS)的基本原理
  3. python自动化办公实例展示_python自动化办公?学这些就够用了
  4. Android解析SVG
  5. python 字符串replace函数_01-Python里字符串的常用操作方法--replace()函数
  6. B树,B+树,红黑树应用场景AVL树,红黑树,B树,B+树,Trie树
  7. python幂运算的符号有哪些及画法_SymPy 符号计算基本教程
  8. 【数据库】数据库系统工程师(软考中级)——学习过程总结
  9. MySQL索引失效、优化的方法
  10. MAC 如何快捷截图
  11. 使用健康档案数据计算OLT的用户光衰不合格率
  12. 游戏排行榜实现mysql_游戏中百万用户排行设计与实现
  13. 深入浅出CChart 每日一课——快乐高四第五十九课 殊途同归,炫彩界面库之C代码风格
  14. LabVIEW控制Arduino采集多路模拟量、数字量(进阶篇—1)
  15. React Native动画Animated详解
  16. 计算机的二三事——软件篇
  17. 表情符号存入mysql_emoji等表情符号存mysql的方法
  18. 《Android系统源代码情景分析》一书勘误
  19. 暴力枚举题:平面上的点与外心
  20. JetBrains学生包续期

热门文章

  1. Discuz!教程之大型Discuz!论坛站点帖子表forum_post分表方案优化
  2. python画函数图像 保留_2.3python如何绘制二次函数图像
  3. Mysql大表数据清理
  4. 红米k40怎样开启NFC步骤分享
  5. iphone6 适配和分辨率
  6. 推荐几款工具,提升十倍工作效率
  7. java入门之控制台输入人数成绩计算及格率(将成绩存入数组)与打印九九乘法表
  8. 数据结构--学生成绩管理系统(顺序表)
  9. XML——XML解析之DOM
  10. 如何管教患有拖延症的娃