1. Ajax Fetch Axios的区别?
-
三者都用于网络请求,但是不同维度
- Ajax(Asynchronous Javascript and XML),一种技术统称
- Fetch,一个原生API
- 浏览器原生API,用于网络请求
- 和XMLHttpRequest一个级别
- Fetch语法更加简洁、易用,支持Promise
- Axios,一个第三方库 axios-http.com/
- 最常用的网络请求lib(随着Vue火爆起来)
- 内部可用XMLHttpRequest和Fetch来实现
-
lib(第三方的工具) 和 API(原生的函数)的区别
-
实际项目中,使用现成的lib,尽量不要自己造轮子
2. 防抖和节流
-
两者有什么区别?分别用于什么场景?
- 防抖,防止抖动,“你先抖动着,啥时候停了,再执行下一步”
- 例如,一个搜索输入框,等输入停止之后,再触发搜索
- 限制执行次数,多次密集的触发只执行一次
- 关注结果
- 节流,节省交互沟通。流,不一定指流量。“别急,一个一个来,按时间节奏来,插队者无效”
- 例如,drag或scroll期间触发某个回调,要设置一个时间间隔
- 限制执行频率,有节奏的执行
- 关注过程
- 防抖,防止抖动,“你先抖动着,啥时候停了,再执行下一步”
-
结果 VS 过程(限制频率)
-
实际工作中可使用lodash.com/
搜索<input id="input1"/>
<script>
function debounce(fn, delay = 200){
let timer = 0
return function() {
if(timer) clearTimout(timer)
timer = setTimeout(() => {
fn.apply(this, arguments) // 透传 this 和 参数
}, delay)
}
}
const input1 = document.getElementById('input1')
input1.addEventListener('keyup', debounce(() => {
console.log('发起搜索', input1.value)
}, 300))
</script>
<div id="div1" draggable="true" style="width:100px; height: 50px; backbround-color: #bfa; padding: 20px;">
可拖拽
</div>
<script>
function throttle(fn, delay = 100) {
let timer = 0
return function(){
if(timer) return
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = 0
}, delay)
}
}
const div1 = document.getElementById('div1')
div1.addEventListener('drag', throttle((e) => {
console.log('鼠标的位置', e.offsetX, e.offsetY)
}, 200))
</script>
3. px % em rem vw/vh有什么区别?
- px 基本单位,绝对单位(其他都是相对单位)
- % 相对于父元素的宽度比例
- em 相对于当前元素的font-size
- rem 相对于根节点的font-size
- vw 屏幕宽度的1%
- vh 屏幕高度的1%
- vmin 两者的最小值;vmax 两者的最大值
4. 箭头函数
- 箭头函数有什么缺点?
- 没有 arguments
- 无法通过apply call bind改变this
- 什么时候不能使用箭头函数?
- Vue组件本质上是一个JS对象
5.请描述TCP三次握手(连接)和四次挥手(断开)
- 先建立连接(确保双方都有收发消息的能力)
- 再传输内容(如发送一个get请求)
- 网络连接是TCP协议,传输内容是HTTP协议
- 三次握手 —— 建立连接
- Client发包,Server接收。Server:有Client要找我
- Server发包,Client接收。Client:Server已经收到消息了
- Client发包,Server接收。Server:Client要准备发送了
- 四次挥手 —— 关闭连接
- Client发包,Server接收。Server:Client已请求结束
- Server发包,Client接收。Client:Server已收到,我等待它关闭
- Server发包,Client接收。Client: Server此时可以关闭连接了
- Client发包,Server接收。Server:可以关闭了(然后关闭连接)
6. for..in和for...of有什么区别?
-
key和value
- for...in遍历得到key
- for...of遍历得到value
-
适用于不同的数据类型
- 遍历对象:for...in可以,for...of不可以
- 遍历Map Set:for...of可以,for...in不可以
- 遍历generator:for...of可以,for...in 不可以
-
for...in 用于可枚举数据,如对象、数组、字符串,得到key
-
for...of 用于可迭代数据,如数组、字符串、Map、Set,得到value
7. Vue computed和watch有什么区别?
- 用途不同
- computed 用于计算产生新的数据,有缓存(对比method)
- watch 不用于监听现有数据
8. Vue组件通讯有几种方式?尽量全面
- 不同场景
- 父子组件
- props
- emits
- $attrs
- 透传 v-bind="$attrs"
- $parent
- $refs onMounted中,可以拿到
- 上下级组件(跨多级)通讯
- provide inject
- 全局组件
- mitter
- vuex / pinia
- 父子组件
9. vuex中mutation和action区别
- mutation:单个操作,必须同步代码
- action:可包含多个mutation,可包含异步代码
10. JS严格模式有什么特点?
11. 跨域
12. Vue每个生命周期都干了什么?
-
beforeCreate
- 创建一个空白的Vue示例
- data method尚未被初始化,不可使用
-
created
- Vue示例初始化完成,完成响应式绑定
- data method 都已经初始化完成,可调用
- 尚未开始渲染模板
-
beforeMounted
- 编译模板,调用render生成vdom
- 还没有开始渲染DOM
-
mounted
- 完成DOM渲染
- 组件创建完成
- 开始由“创建阶段” 进入 “运行阶段”
-
beforeUpdate
- data发生变化之后
- 准备更新DOM(尚未更新DOM)
-
updated
- data发生变化,且DOM更新完成
- 不要再updated中修改data,可能会导致死循环
-
beforeUnmount
- 组件进入销毁阶段(尚未销毁,可正常使用)
- 可移除、解绑一些全局事件、自定义事件
-
unmounted
- 组件被销毁了
- 所有的子组件也被销毁了
-
keep-alive组件
- onActivated 缓存组件被激活
- onDeactivated 缓存组件被隐藏
-
连环问:Vue什么时候操作DOM比较合适
- mounted和updated都不能保证子组件全部挂载完成
- 使用$nextTick渲染DOM
-
连环问:Ajax应该在哪个生命周期?
- 有2个选择: created和mounted
- 推荐: mounted(created和mounted之间就差几ms,差别微乎其微)
-
Vue3 Composition API生命周期有何区别?
- 用setup代替了beforeCreate和created
- 使用Hooks函数的形式,如mounted改为onMounted()
13. Vue React中为何循环时必须使用key?
- vdom diff算法会根据key判断元素是否删除
- 匹配了key,则只移动元素 - 性能较好
- 未匹配key,则删除重建 - 性能较差
14. 网络请求中,token和cookie有什么区别?
- HTTP无状态,每次请求都要带cookie,以帮助识别身份
- 服务端也可以向客户端set-cookie,cookie大小限制4kb
- 默认有跨域限制:不可跨域共享、传递cookie
-
cookie本地存储
- HTML5之前cookie常被用于本地存储
- HTML5之后推荐使用localStorage和sessionStorage
-
现代浏览器开始禁止第三方cookie
- cookie和session
- token vs cookie
- cookie是HTTP规范,而token是自定义传递
- cookie会默认被浏览器存储,而token需自己存储
- token默认没有跨域限制
-
JWT(JSON Web Token)
- 前端发起登录,后端验证成功之后,返回一个加密的token
- 前端自行存储这个token(其中包含了用户信息,加密了)
- 以后访问服务端接口,都带着这个token,作为用户信息
-
答案
- cookie:HTTP标准;跨域限制;配合session使用
- token: 无标准;无跨域限制;用于JWT
15. session 和 JWT哪个更好?
-
session
-
优点:
- 原理简单,易于学习
- 用户信息存储在服务端,可快速封禁某个用户
-
缺点:
- 占用服务端内存,硬件成本高
- 多进程,多服务器时,不好同步 —— 需使用第三方缓存,如redis
- 默认有跨域限制
-
-
JWT
-
优点:
- 不占用服务端内存
- 多进程、多服务器不受影响
-
缺点:
- 用户信息存储在客户端,无法快速封禁某用户
- 万一服务端秘钥被泄露,则用户信息全部丢失
- token的体积一般大于cookie,会增加请求的数据量
-
-
答案:
- 如有严格管理用户信息的要求(保密、快速封禁)推荐Session
- 如没有特殊要求,则使用JWT(如创业初期的网站)
16. 如何实现SSO单点登录?
- 基于cookie
- cookie默认不跨域共享,但有些情况下可设置共享
- 主域名相同,如
www.baidu.comimage.baidu.com - 设置cookie domain为主域名,即可共享cookie
- 主域名不同 则用SSO
17. 描述从输入url到页面展示的完整过程
- 网络请求
- DNS查询(得到IP),建立TCP连接(三次握手)
- 浏览器发起HTTP请求
- 收到请求响应,得到HTML源代码
- 继续请求静态资源
- 解析HTML过程中,遇到静态资源还会继续发起网络请求
- JS CSS 图片 视频等
- 注意:静态资源可能有强缓存,此时不必请求
- 解析: 字符串 -> 结构化数据
- HTML构建DOM树
- CSS构建CSSOM树(style tree)
- 两者结合,形成render tree
- 优化解析
- CSS放在
<head>中,不要异步加载CSS - JS放在
<body>最下面(或合理使用defer async) <img>提前定义width height
- CSS放在
-
渲染:render tree 绘制到页面
- 计算各个DOM的尺寸、定位,最后绘制到页面
- 遇到JS可能会执行(参考defer async)
- 异步CSS、图片加载,可能会触发重新渲染
-
答案:
- 网络请求:DNS解析,HTTP请求
- 解析:DOM树,CSSOM树,Render Tree
- 渲染:计算、绘制,同时执行JS
18. 重绘repaint 和 重排reflow有什么区别?
-
动态网页,随时都会重绘、重排
- 网页动画
- Modal Dialog弹窗
- 增加/删除一个元素,显示/隐藏一个元素
-
重绘
- 元素外观改变,如颜色、背景色
- 但元素的尺寸、定位不变,不会影响其他元素的位置
-
重排
- 重新计算尺寸和布局,可能会影响其他元素的位置
- 如元素高度增加,可能会使相邻元素位置下移
-
区别
- 重排比重绘要影响更大,消耗也更大
- 所以,要尽量避免无意义的重排
-
减少重排的方法
- 集中修改样式,或直接切换css class
- 修改之前先设置display: none,脱离文档流
- 使用BFC特性,不影响其他元素位置
- 频繁触发(resize scroll) 使用节流和防抖
- 使用createDocumentFragment批量操作DOM
- 优化动画,使用CSS3和requestAnimationFrame
-
扩展:BFC
- Block Format Context 格式化上下文
- 内部的元素无论如何改动,都不会影响其他元素的位置
- 触发BFC的条件
- 根节点
<html> - float: left/right;
- overflow: auto/scroll/hidden;
- display: inline-block/table/table-row/table-cell;
- display: flex/grid; 的直接子元素
- position: absolute/fixed
- 根节点
19. script标签的defer和async有什么区别?
- 答案:
- 无:HTML暂停解析,下载JS,执行JS,再继续解析HTML
- defer: HTML继续解析,并行下载JS,HTML解析完再执行JS
- async: HTML继续解析,并行下载JS,执行JS,再解析HTML
20. 如何实现网页多标签tab通讯?
-
使用WebSocket
- 无跨域限制
- 需要服务端支持,成本高
-
通过localStorage通讯
- 同域的A和B两个页面
- A页面设置localStorage
- B页面可监听到localStorage值的修改
-
通过SharedWorker通讯
- SharedWorder是WebWorker的一种
- WebWorker可开启子进程执行JS,但不能操作DOM
- SharedWorker 可单独开启一个进程,用于同域页面通讯
-
答案:
- WebSocket需要服务端支持,成本较高
- localStorage简单易用,推荐使用
- ShartedWorker 调试不方便,不兼容IE11
21. 如何实现网页和iframe之间的通讯?
- 使用postMessage通讯
- 注意跨域的限制和判断
22. HTTP协议1.0 1.1 2.0有什么区别?
-
HTTP 1.0
- 最基础的HTTP协议
- 支持基本的GET POST方法
- 基本弃用
-
HTTP 1.1
- 增加缓存策略 cache-control E-tag等
- 支持长连接 Connection: keep-alive,一次TCP连接多次请求
- 断点续传,状态码 206, 如大文件分片上传
- 支持新的方法 PUT DELETE等,可用于Restful API
- 常用
-
HTTP 2.0
- 可压缩header,减少体积
- 多路复用,一次TCP连接中可以多个HTTP并行请求
- 服务端推送
23. 什么是HTTPS中间人攻击?如何预防
- HTTPS加密传输
- HTTP明文传输,不安全
- HTTPS加密传输 HTTP+ TLS/SSL
24. 前端攻击有哪些?该如何预防?
- XSS
- Cross Site Script 跨站脚本攻击
- 手段:黑客将JS代码插入到网页内容中,渲染时执行JS代码
- 预防:特殊字符替换(前端或者后端)
- 注意:Vue中v-html可能导致XSS攻击
-
CSRF
- Cross Site Request Forgery跨站请求伪造
- 手段:黑客诱导用户去访问另一个网站的接口,伪造请求
- 预防:严格控制跨域 + 验证码机制
- 严格的跨域请求限制,如判断referrer(请求来源)
- 为cookie设置SameSite,禁止跨域传递cookie
- 关键接口使用短信验证码
- 详细过程:
- 用户登录了A网站,有了cookie
- 黑客诱导用户到B网站,并发起A网站的请求
- A网站的API发现有cookie,认为是用户自己操作的
-
点击劫持
- click Jacking
- 手段:诱导界面上蒙一个透明的iframe,诱导用户点击
- 预防:让iframe不能跨域加载