前端知识体系
2022-04-24 19:15:10 0 举报
AI智能生成
前端知识体系
作者其他创作
大纲/内容
canvas
webGL
echart可以只负责图中红框部分的实现
echart
图形可视化
node
微信小程序
uniapp
小程序
输入网址,浏览器进程开始处理你输入的内容
则开始跳到默认搜索引擎,执行搜索
如果不是网址
判断是否存在缓存,是的话,读取缓存并渲染,否则向服务器发送请求
如果是网址
之后把控制权交给网络进程
浏览器进程
得到IP地址,发起请求
DNS解析
nginx 进行处理 (如果有负载均衡,会发送到各地对应的服务器进行处理)
Nginx负载均衡
客户端发送SYN到服务器
服务器接收到SYN,并生成ACK,发送给客户端
客户端接收到服务的的SYN和ACK,标志连接建立成功
客户端发送ACK给服务端
过程
为什么要三次握手
问题
http连接
发送加密协议和版本给服务端
客户端
返回证书和公钥
服务端
使用根证书验证证书合法性
生成对称密钥
通过公钥加密,把对称密钥发送给服务端
使用私钥解密,获取对称密钥,使用对称密钥加密数据
解密数据,建立SSL连接
https连接
建立连接
浏览器将读取HTTP的 Location 字段,执行重定向
永久重定向
301
临时重定向
302
300
开始读取 Content-Type 字段,判断文件 MIMIE 类型并进行渲染
200
nginx 是否有404 页面 或者 自定义 nginx 404 内容没有,执行浏览器默认的异常有,nginx 返回相关数据,开始渲染
404
状态码
读取服务器数据
客户端发送FIN=1到服务器 服务端发送ACK到客户端,此时仍然可以发送接收数据 服务端发送FIN=1,表示数据已经发送完成客户端发送ACK到服务端,断开连接
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。
简述
这是 TCP 的半关闭(half-close)特性所造成的。
TCP 连接是全双工的(数据在两个方向上可以同时传递),因此每个方向就必须能够单独的关闭。就比如客户端在步骤一执行了半关闭操作后,只是通知服务器它没有数据要发送了,并不代表它不能接收数据。因此,只要服务器还没有主动关闭,就能够向客户端继续发送数据。
当服务器没发完数据时,会先回复一个ACK报文,告诉Client端,\"你发的FIN报文我收到了\"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。
原因
连接的时候是三次握手,关闭的时候却是四次握手
我们必须假象网络是不可靠的,有可能服务端最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
为什么是2MSL,主要是为了考虑到如果最后一个ACK丢失,服务端会重新发FIN,一个来回客户端等待2MSL,才能接收到服务端重新发送的FIN报文。
TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态
为什么
http
客户端断开连接,发送close_notify
https
断开连接
浏览器进程的网络进程
其实是根据相关语义,通过词法分析和语法分析,开始构建 Token,如果不合法,将会在解析过程抛出异常
定义
display:none
注释
script
html文档里的所有标签元素会出现在DOM树中
DOM树
css加载不会阻塞DOM树的解析与生成
CSSOM树可以与DOM树同时构建
CSSOM树提供给 JavaScript 操作样式表的能力
为render tree的合成提供基础的样式信息
css解析规则是从后往前进行解析的,这样的好处就是可以最快的找到被选择的样式,如果从前往后解析,可能会导致解析到一半发现不对,会再次重新解析。
特性
CSS规则树
如果js脚本之前有css文件或者js里操作了css。那么css会在js之前加载
JavaScript 会阻止DOM树的解析
设置了async的script会并行下载,并立即执行
defer 会在dom解析的时候下载,但是会等dom解析完成后再去执行
解析js(如果有)
CSS会阻塞render tree的生成,进而会阻塞DOM的渲染
display: none的元素不在Render Tree中
visibility: hidden的元素在Render Tree中
每个Node节点都是可见节点
每个Node节点都含有其内容和对应规则的样式。
render tree
渲染树布局(layout of the render tree)
光栅化,渲染可视区域
绘制完成后屏幕上显示页面内容
渲染树绘制(Painting the render tree)
页面生成过程
解析
背景色、颜色、字体改变(注意:字体大小发生变化时,会触发回流)
重绘 Repaint
页面第一次渲染(初始化)
DOM树变化(如:增删节点)
Render树变化(如:padding改变)
浏览器窗口resize
获取元素的某些属性
重排(回流) Reflow
样式集中改变
批量操作 DOM
使用 **absolute** 或 **fixed** 使元素脱离文档流
减少重绘重排
用户访问网页时不断触发
渲染进程
渲染过程
浏览器向目标 URI 发 Ajax 请求时,只要当前 URL 和目标 URL 不同源,则产生跨域请求
响应其实是成功到达客户端,但被浏览器所拦截
浏览器的同源策略
在渲染进程处理的时候,Ajax 请求准备发送,然后渲染进程通过进程间的通信通知到主进程,主进程发起网络请求,发起了Ajax请求
服务端返回响应,主进程检查到跨域,且没有cors响应头,将响应体全部丢掉,并不会发送给渲染进程。这就达到了拦截数据的目的
不能读取和修改不同源html的 DOM
不得访问不同源的 Cookie、IndexDB 和 LocalStorage
限制不同源的 XMLHttpRequest 请求
具体限制
W3C 的一个标准,全称是跨域资源共享
需要浏览器和服务器的共同支持
特点
GET
POST
HEAD
请求方法
Accept
Accept-Language
Content-Language
Last-Event-ID
application/x-www-form-urlencoded
multipart/form-data
text/plain
Content-Type(三值之一)
HTTP的头信息不超出以下几种字段
需要同时满足才是简单请求
Origin字段向服务器说明,本次请求来自于哪个源(协议+域名+端口)
在请求头当中,添加一个Origin字段
浏览器
服务器在回应时对应地添加Access-Control-Allow-Origin字段
如果允许跨域请求
表示是否允许发送 Cookie
Access-Control-Allow-Credentials
服务器添加的某些功能响应字段
服务器
如果Origin不在这个字段的范围中,那么浏览器就会将响应拦截
对简单请求的处理
简单请求
不是简单请求的就是非简单请求
OPTIONS
源地址
Origin
目标地址
Host
CORS 请求用到哪个HTTP方法
Access-Control-Request-Method
真正的CORS 请求将要加上什么请求头
Access-Control-Request-Headers
请求头部字段
预检请求
可以允许请求的源,可以填具体的源名,也可以填*表示允许任意源请求
Access-Control-Allow-Origin
表示允许的请求方法列表
Access-Control-Allow-Methods
跨域请求是否允许浏览器发送 Cookie
表示允许发送的请求头字段
Access-Control-Allow-Headers
预检请求的有效期,在此期间,不用发出另外一条预检请求
Access-Control-Max-Age
允许跨源请求,服务器返回CORS字段
处理
不允许跨域请求,服务器返回的请求头没有任何CORS字段
预检请求的响应
浏览器自动加上Origin字段
服务端响应头返回Access-Control-Allow-Origin
CORS请求
对复杂请求的处理
非简单请求
对不同请求的处理
CORS
类似于vuecli里设置proxyTable
此时在浏览器里显示请求的api接口是反向代理服务器的ip地址,不是真实服务器的ip,反向代理服务器会修改url用于和真实服务器交互
nginx反向代理
document.domain
postMessage
只支持 GET 请求
兼容性好,IE 低版本不能使用 CORS 但可以使用 JSONP
XMLHttpRequest对象遵循同源政策,但是script标签不一样,它可以通过 src 填上目标地址从而发出 GET 请求,实现跨域请求并拿到响应。
原理
jsonp
解决方案
跨域
网络进程
浏览器主进程
插件进程
GPU进程
进程
gecko 火狐
webkit 苹果
blink 谷歌
浏览器引擎
把所有活动对象做上标记
标记阶段
把没有标记(也就是非活动对象)销毁
清除阶段
分配速度慢
内存碎片化
标记整理(Mark-Compact)算法
解决
缺点
标记清除
需要一个计数器
解决不了循环引用导致的无法回收
引用计数
采用并行回收
新生代内存
采用增量标记与懒性清理
老生代内存
将堆内存分为
V8垃圾回收机制
垃圾回收
打开网页,地址栏输入地址
普通刷新 (F5)
强制刷新 (Ctrl + F5)
缓存策略
移动端
终端
思维导图
javaScript设计模式
html
src
代表ES6模块
module
text/javascript
type
立即异步下载脚本,不会阻塞html解析,下载完成后立即执行。所有async标识的script乱序执行
async
立即异步下载脚本,不会阻塞html解析,在所有dom元素解析完成之后执行。所有defer标识的script顺序执行
defer
使得script不会阻塞DOM的渲染
属性
其他标签
文档元信息
语义相关内容
链接
表单
表格
标签分类
Tag
继承自XML的部分
createElement
createTextNode
createDocumentFragment
createAttribute
创建节点
querySelector
querySelectorAll
查询节点
innerHTML
innerText
textContent
style
更新节点
appendChild
insertBefore
setAttribute
添加节点
removeChild
删除节点
对象模型-维基百科
DOM
事件
location
navigator
screen
history
window
window.innerHeight
window.innerWidth
浏览器视窗的大小(不包括顶部的菜单栏)
有滚动条时,滚动条向下滚动的距离
scrollTop
offsetTop
Top
一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容
scrollHeight
元素在浏览器窗口中的可见高度 + 浏览器窗口中元素自身padding
clientHeight
也是元素在浏览器窗口中的可见高度 + 在浏览器窗口中自身padding + 在浏览器窗口中自身border + 滚动条
offsetHeight
Height
文档内部属性
元素的顶端将和其所在滚动区的可视区域的顶端对齐
element.scrollIntoView(true)
元素的底端将和其所在滚动区的可视区域的底端对齐
element.scrollIntoView(false)
Element.scrollIntoView()
Document
Nodes
BOM-维基百科
BOM
API
浏览器环境
Node环境
Electron环境
小程序环境
增加代码可读性
有助于seo
在没有 CSS 样式下,页面也能呈现出很好地内容结构、代码结构。
语义化
HTML
.class
#id
tagname
*
属性选择器: [attr=val]
简单选择器
复合选择器
复杂选择器
选择器列表
:before
:after
伪元素
优先级
分类
!important > style > id > class
文档
选择器
px
设置rem与根元素的font-size(px)的对应关系,再通过rem去设置元素宽高,最后动态调整根元素的font-size就能响应式
引入pxtorem插件
引入脚本动态调整根元素font-size的值
使用
rem
100vw就是屏幕的总宽度
vw/vh
单位
正常文档流
弹性布局
排版布局
从属性值为A变到B的单个动作
transition
属性值从A到B,B到C...的多个动作
animation
页面呈现的是静止的最终状态
translate
动画
根层叠上下文
普通元素设置position属性为非static值 并设置z-index属性为具体数值(不是auto)
display属性值为flex
opacity属性值不是1
CSS3中的新属性
层叠上下文
层叠顺序
层叠等级
z-index
flex布局的容器里的项目能按原来的大小显示
项目设置flex:1,能使项目按照所剩空间大小自适应的伸缩
flex
机制
标准盒模型
IE(替代)盒模型
content + padding + border + margin
构成
避免高度塌陷
避免 margin 重叠问题
BFC 是独立的容器,容器内部元素不会影响外部元素。
在 同一个BFC 中上下相邻的两个容器的 margin 会重叠,创建新的 BFC 可以避免外边距重叠。
计算 BFC 的高度时,需要计算浮动元素的高度
BFC
设置的width/height只包含 content
设置的width/height包含content + padding + border的总长度
盒子内容宽/高度(即 width/height)
content+padding
背景色
box-sizing
盒模型
margin-top 负值,元素向上移动
margin-bottom 负值,下方元素向上移动
margin-left 负值,元素向左移动
margin-right 负值,右侧元素向左移动
负值margin
值为百分比,用父元素的font-size *百分比
line-height
基础
形成机制
异步获取content的数据
BetterScroll
插件
滚动条
css标准查询
CSS
单线程
多线程
线程
HTML 解析器
解析html代码,生成DOM树
CSS解析器
解析css,生成CSS规则树
生成渲染树
绘制网页最终显示
回流,重绘
功能
GUI渲染线程
1、扫描分类
主线程中的宏任务执行然后执行该宏任务产生的微任务若微任务在执行过程中产生了新的微任务,则继续执行微任务,宏任务按照延迟时间来排序执行,相同的延迟时间按插入顺序执行微任务执行完毕后,再回到宏任务中进行下一轮循环。
2、执行回调任务
执行顺序
浏览器的事件循环
Node的事件循环
空格
换行符/回车
单行注释
多行注释
符号
变量名
属性名
函数名
自定义名称
var
function
new
const
let
自动生成块级作用域
constructor
super
extend
class
关键字(KeyWords)
IdentifierName(标识符)
正则表达式字面量
数字字面量(NumericLiteral)
字符串字面量(StringLiteral)
Boolean
Null
Undefined
Symbol
基本类型字面量
{}
Object(对象字面量)
引用类型字面量
csdn
Literal-- 字面量
Token
词法(Lexical)
ECMAScript
标准:
书写规则
Infinity
-Infinity
安全的整数范围
先tofixed取指定位数的小数,同时tofixed返回结果为字符串,字符串再通过parseInt()转整数或parsefloat()转小数
解决方法
乘2取整法来表示小数,但是0.1和0.2都表示不出来,所以就有问题了
浮点数比较
toFix()
mathjs插件
精度问题解决
Number
不接受负的参数
ECMAscript 没有对该方法进行标准化,因此反对使用它。
截取
字符串转数组
split(\"\")
转换
charAt(index)
match(regexp)
查
单引号语法
双引号语法
通过代码如何实现字符串模板
反引号语法
语法
String
BigInt
基本类型
__proto__
prototype
defineProperties()
defineProperty() 修改属性的默认特性
getOwnPropertyNames()
setPrototypeOf()
Object这个构造函数上的方法
hasOwnProperty()
isPrototypeOf()
Object的原型(Object.prototype)上的方法
方法
object
创建数组
slice()
concat()
map()
filter()
includes() some() every()
indexOf()
join() toString()
reduce()
不改变原数组
arr.push()
arr.unshift()
arr.shift()
arr.pop()
arr.sort()
arr.reverse()
会修改原来的数组
是否改变原数组
直接用item=xxx的形式,来给形参item赋值无法改变原数组
用arr[index]就可以改变原数组
数组里面的子元素是对象,那么是可以改变对应属性
map
filter
不能提前终止中断循环
every
some
for
find
findIndex
遍历的是对象属性名字或数组的索引,没有遍历到\"值\"
for in
能直接遍历数组中的每一项
for of
能提前终止循环
reduce
迭代器
array
箭头函数
普通函数
(function (){}) 直接声明
var a = function(){} 赋给变量
function a { return function(){}} 作为返回值
匿名函数
函数分类
箭头函数的this就是定义该函数时所在的作用域指向的对象
font color=\"#e57373\
匿名函数的this在调用(运行)时确定,指向调用函数对应的对象
怎么确定
call 第二个参数之后是个列表
apply 第二个参数是个数组
bind 会返回一个新的函数,并且只会改变一次 this
修改this指向的api
知乎
this
函数内部嵌套了一个新的函数,嵌套的函数对外部的函数造成了引用就形成了闭包
柯里化
节流、防抖
compose 组合函数
应用
闭包
扩展运算符
普通调用
调用函数
rest参数
定义函数
函数的使用
Date
不能处理函数
JSON.parse(JSON.stringify())
深拷贝
要拷贝的值是原始类型时是深拷贝
要拷贝的值是对象类型时是浅拷贝
assign()
适用value是基本类型,或者引用类型只有一层的情形
... 展开运算符
例子
浅拷贝
拷贝
数组实例的 constructor 属性等于Array()构造函数
数字实例的 constructor 属性等于Number()构造函数
字符串实例的 constructor 属性等于String()构造函数
对象实例的 constructor 属性等于Object()构造函数
函数实例的constructor 属性等于Function()构造函数
constructor 属性返回对象的构造函数。
每个函数都有一个prototype属性,这个prototype的constructor指向这个函数
原型与原型链
引用类型
不可对 null、对象(Object)、数组(Array)进行精确判断,因为都返回 object
判断基本类型用typeof
能判断对象类型
不能判断基本数据类型
判断引用类型用instanceof
所有都能判断
Object.prototype.toString.call()
如何判断为数组类型
类型判断
Boolean()
显式转换
有逻辑判断的地方
逻辑运算符(比如||和&&)是在内部做了boolean类型转换,但实际上返回的是原始操作数的值
有逻辑运算符的地方
隐式转换
除了“0/NaN/空字符串/null/undefined”五个值是false,其余都是true
转换为boolean
String()
有 + 运算符且有一个操作数是 string 类型时被触发,不会触发 number 类型的隐式转换
转化为String
Number()
[\"1\
parseInt()
转化为number
类型转换
将json对象转换成js对象的形式
JSON.parse()
将js对象转换成json对象
JSON.stringify()
用于post的application/json方式提交
json
处理url参数('http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e'问号后面的内容)的js库
把一段url参数转换为对象格式
qs.parse
把一个对象格式化为一段url参数
qs.stringify
用于post的application/x-www-form-urlencoded方式提交
qs库
^
$
\\b
\\B
有一个位置,紧跟其后需要满足p子模式
?=p
(?!p)
(?<=p)
(?<!p)
表示位置的符号
匹配位置
量词
横向
排除字符组
常见简写
字符组
纵向
模糊匹配
多选分支
匹配字符串
让量词作用于一个整体
分组
分支
正则不带g返回所有结果,带g返回最长的结果
match
test
提取数据
每一个符合第一个参数(正则表达式条件)的子字符串
$0
第1-9个匹配的括号内容
$1-$9
函数的形参
表示对每个符合的结果使用函数来处理
函数
引用正则表达式里某一个分组
字符串
API的第二个参数
正则表达式
API的第一个参数
replace
数据替换
分组引用
括号的作用
特殊数据类型
数据类型
commonJS
ESmodel
模块规范
JavaScript
此时this表示window对象
全局执行上下文
函数上下文
eval上下文
全局上下文中的变量对象就是全局对象window
全局上下文里称为变量对象(Variable object,VO)
找到了
从父级执行上下文的变量对象中查找
没找到
首先从当前上下文的变量对象中查找
变量对象的查找规则
变量对象
由多个执行上下文的变量对象(VO)构成的链表就叫做作用域链
概念
查找变量
用途
全局作用域
函数作用域
搭配let const 使用
块级作用域
作用域
作用域链(Scope chain)
全局上下文
重要属性
函数的所有形参 (如果是函数上下文)
如果存在相同名称的属性,则完全替换这个属性
替换规则
函数声明
如果存在相同名称的属性,则变量声明不会替换已经存在的这类属性
变量声明
对象内包括
生成变量对象
scope属性没有包含自身的AO对象
复制函数[[scope]]属性创建作用域链
将活动对象压入作用域链顶端
生成作用域链(Scope chain)
执行上下文对象被压入执行上下文栈
会顺序执行代码,修改变量对象的值
代码执行
执行上下文代码的执行过程
执行上下文对象
栈内组成
函数被调用时入栈
入栈
运行栈顶的上下文,运行完后出栈,直到栈内没有上下文
将微任务事件队列的回调函数压入栈中,执行回调
有
没有
执行栈为空时,向事件触发线程发起询问,是否有微任务的回调函数
执行
运行机制
执行栈
new Promise函数的特殊点
new Promise()在resolve()或reject()之前的代码
await 同一行上面的代码
await 同一行后面的函数语句会立即执行函数语句里的同步代码
同步任务
Event Table会将函数移到宏任务事件队列中
当完成指定事件时
在Event Table注册回调函数
进入宏任务Event Table
每一个宏任务会从头到尾执行完毕,不会执行其他
setTimeout
setInterval
I/O
UI Rendering//UI事件
postMessage,MessageChannel
setImmediate
宏任务
Event Table会将函数移到微任务事件队列中
进入微任务Event Table
当一个宏任务执行完,会在渲染前,将执行期间所产生的所有微任务都执行完。在同一轮事件循环内执行
Process.nextTick
c
相当于
chrome内部实现的Promise和标准的Promise/A+规范存在差异
b
Promsie状态变为fulfilled,拿到成功的值的过程并不需要等待。而是拿到它的值之后,在向后运行的时候,会产生微任务
Promise.resolve()函数将类promise对象的多层嵌套展平
a
Promise.resolve()会解决promise嵌套的情况,同步执行拿到结果值
resolve(a)和.then reject()和.catch的执行顺序
resolve(),reject()后面的语句还会执行
resolve() reject()执行时机
Promise.then()
resolve后面的then回调函数在本轮“事件循环”(event loop)的结束时执行,不是在下一轮“事件循环”执行
Promise.resolve()
返回值是一个Promise
fulfilled
rejected
padding
状态
Promise
Promise.then() .catch() .finally()括号里面的内容
MutationObserver
await后面不同行的语句相当于Promise的then回调函数
await
Async/Await
微任务
异步任务
分类<script>代码
为什么用js操作DOM慢
JS引擎线程(主线程)
宏任务队列
微任务队列
事件队列FIFO
事件的传播顺序为从根节点到触发的的具体元素
捕获
触发
事件的传播顺序为从事件开始的具体元素直到根节点
冒泡
event事件流
事件触发线程
定时触发器线程
通知浏览器主进程发起网络请求
异步http请求线程
Event Loop(事件循环)
用于3D绘制
多进程
事件修饰符
父组件内
出现位置
具名插槽
作用域插槽
用法
v-slot
在没有key的情况下(或者使用index),diff过程中,无法确定具体更新的节点,会导致删除的节点错误,所以需要一个唯一的key值,用于渲染更新,如果你不需要增删的话,用index其实也没啥问题
为什么需要key
v-for
v-show通过display none 和block属性进行控制
如果用在组件上。每一次显隐都会使组件重新跑一遍生命周期,因为显隐决定了组件的生成和销毁
v-if 通过增删改节点进行显示控制
v-if和v-show
不要同时在一个div中使用
v-for和v-if
v-model
指令
子组件/UI插件名
子组件内
默认内容
<slot>
特殊标签
变量名为true就使用样式
变量名为false就不使用此样式
{样式名:变量名}
:class
变量名为具体的属性值
{css属性名:变量名}
:style
样式
template标签内的标签
render
是一个函数
处理不需要响应式的数据
data
缓存机制
不能进行异步操作
computed
可以进行异步操作
watch
method
组件内的语法使用
规则
props、emit
$parent、$children
proivde、inject
$attrs
$listeners
手写实现
EventBus
方式
传值
mixins
extends
watch、钩子函数
data、computed、methods、props
聚合
组件间
由于Vue更新Dom是异步更新,所以使用 this.属性 赋值后在下一行代码不能马上获取更新后的内容
现象
判断是否支持Promise
判断是否支持MutationObserver
判断是否支持setImmediate (IE9 以上支持)
降级为setTimeout实现
判断
选择浏览器支持的函数方法来包装并执行
执行过程
这里主要使用了事件循环的机制,通过一个callbacks数组用来维护需要异步更新的数据,遍历callbacks数组并执行
vue执行完渲染后会执行this.nextTick()里面的callback函数。
在给插件实例初始化的时候
何时用
nextTick
如果目标值有多个,结果是一个数组
this.$refs
this.$options
当前值,会获取改变后data的最新值
this.$data
全局方法
初始化生命周期
初始化events
初始化render
调用beforeCreated和created
调用_init
给Vue原型添加_init方法
initMixin
给原型挂载$data、$props
stateMixin
new Vue
初始化data、computed、watch、props 可用于第三方插件在该钩子内通过Vue.use进行挂载
beforeCreate
初始化provide、inject
created
beforeMount
mounted
beforeUpdate
updated
beforeDestory
destoryed
v2
替代掉v2的beforeCreate、created 该函数执行完成后会开始把模板编译成render function
setup
在渲染前触发
onBeforeMount
渲染后触发
onMounted
onBeforeUpdate
onUpdated
销毁前
onBeforeUnmount
销毁完成
onUnmounted
内部实现了一个createHook,该函数内会去执行一个injectHook,并把组件内的生命周期函数保存到组件实例上,之后在执行渲染、更新销毁的时候,会去从组件实例取出并执行
生命周期是怎么执行的?
除了beforeCreate、created在v3移除了,其余没啥变化
v3
版本间的不同
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
父beforeUpdate 子beforeUpdate 、updated、父updated
父beforeDestory 子beforeDestory 、destoryed、父destoryed
父子组件生命周期
hook
特殊用法
生命周期
通过definePropery对data内的属性遍历添加getter、setter属性,通过watcher对Dep进行依赖收集管理,内部会通过Dep.target去维护一个当前的watcher,当数据更新的时候会去执行dep.notify方法,依次遍历当前dep内的watcher 进行数据更新
Observer 用于添加getter和setter
Dep 进行依赖收集 (收集的依赖就是watcher)
watcher 主要负责保存依赖,从而在数据更新的时候,触发渲染
data watcher
watch watcher
computed watcher
类别
Watcher
由于性能问题,Vue针对push、pop、shift、unshift、sort、splice、reverse的7个方法做了拦截处理(因为这7个会改变原有数组),进行更新。
针对数组的处理
在Vue2中,提供了$set的方式用于解决数据无法更新的问题,会先判断是否可以添加响应,可以的话,就调用defineReactive添加相应,并触发dep.notify执行更新
$set
判断是否可以删除响应,并且不是私有属性和$data上的属性,就执行删除,继续调用dep.notify更新
$delete
针对无法更新的处理
V2
响应式原理
diff
性能优化
写法优化
优化
vue3
Vue
React
业务逻辑主要集中在Controller
当每个事件都流经Controller时,这层会变得十分臃肿
View和Controller一般是一一对应的,视图与控制器间过于紧密让Controller的复用性差
MVC
MVVM把View和Model的同步逻辑自动化
Vue是MVVM框架,但是不是严格符合MVVM,因为MVVM规定Model和View不能直接通信,而Vue的ref可以做到这点
MVVM
简化了业务与界面的依赖,还解决了数据频繁更新
低耦合模式提高代码的可重用性
MVVM 比 MVC 精简
区别
框架设计模式
框架
rollup
提供了终端里的 vue 命令
CLI(@vue/cli)
包含优化过的默认 webpack 配置
构建于 webpack 和 webpack-dev-server 之上
启动一个开发服务器 (基于 webpack-dev-server) 和模块热重载 (Hot-Module-Replacement)。
serve
build
inspect
vue-cli-service
CLI服务(@vue/cli-service)
@vue/cli-plugin-
内建插件
vue-cli-plugin-
社区插件
生成器
运行时插件
组成
当你在项目内部运行 vue-cli-service 命令时,它会自动解析并加载 package.json 中列出的所有 CLI 插件
加载其它 CLI 插件的核心服务
CLI插件
则无视配置的浏览器兼容,引入所有的 polyfill
false
根据配置的浏览器兼容,引入浏览器不兼容的 polyfill。在项目入口引入一次(多次引入会报错)
2
3
corejs
entry
会根据配置的浏览器兼容,以及你代码中用到的 API 来进行 polyfill,实现了按需添加
默认值,从@vue/babel-preset-app传过来
usage
useBuiltIns
核心配置项
@babel/preset-env
确定项目的目标浏览器的范围
作用
package.json 文件里的 browserslist 字段
一个单独的 .browserslistrc 文件
位置
@babel/preset-env 和 Autoprefixer 根据范围来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀
被谁处理
browserslist字段
使用@vue/babel-preset-app来polyfill(Vue CLI默认使用的集成转译插件)
Polyfill
将其添加到 vue.config.js 中的 transpileDependencies 选项
该依赖基于一个目标环境不支持的 ES 版本撰写
使用 @vue/babel-preset-app 的 polyfills 选项预包含所需要的 polyfill
该依赖交付了 ES5 代码并显式地列出了需要的 polyfill
该依赖交付 ES5 代码,但使用了 ES6+ 特性且没有显式地列出需要的 polyfill
如果有依赖(或第三方包)需要 polyfill
兼容浏览器
public/index.html
处理对象
JavaScript 和 CSS 文件的资源链接
让浏览器提前加载指定资源(加载后并不执行),需要执行时再执行
默认情况下,一个 Vue CLI 应用会为所有初始化渲染需要的文件自动生成 preload 提示
浏览器一定会加载
preload
利用浏览器的空闲时间加载非首页的其他页面所需要的资源,以便加快后续页面的首屏速度
默认情况下,一个 Vue CLI 应用会为所有作为 async chunk 生成的 JavaScript 文件 (通过动态 import() 按需 code splitting 的产物) 自动生成 prefetch 提示。
prefetch
manifest 和图标链接
自动注入资源链接到html
html-webpack-plugin插件
决定最终的文件路径
file-loader
通过 style 标签的方式嵌入进了 HTML 里面
内联 CSS
将小图片通过 base64 的方式内嵌进 CSS 里面
内联图片
将小于 4kb 的资源内联,以减少 HTTP 请求的数量
url-loader
URL 以 . 开头
引用一个 npm 依赖中的文件
URL 以 ~ 开头
URL以 @ 开头
使用相对路径导入
webpack 处理
通过 <%= BASE_URL %> 设置链接前缀
在 public/index.html引用
需要向你的组件传入基础 URL再引用
在vue模板中
需要通过绝对路径引用
需要在构建输出中指定一个文件的名字
有上千个图片,需要动态引用它们的路径
有些库可能和 webpack 不兼容,这时你除了将其用一个独立的 <script> 标签引入没有别的选择。
何时要放到public文件加下?
public 目录下的资源
打包后的绝对路径保留不变
直接通过绝对路径引用
以web站点根目录为参考基础的目录路径
绝对路径
不会经过 webpack 的处理
处理静态资源
HTML 和静态资源
给所有的样式都加上一个 scoped 的属性
vue-loader
解析其中的url()引用
把样式都变成 module 形式,然后直接导出这个模块,模块中包含了 css 的源码跟模块的 id
css-loader
创建了一个 style 标签,然后直接插入到了dist的html文件的 head 标签中
vue-style-loader
编译过程
PostCSS 提供了一个解析器,它能够将 CSS 解析成抽象语法树(AST)
它能够为 CSS 提供额外的功能
vue.config.js 中的 css.loaderOptions.postcss 配置 postcss-loader
postcss-pxtorem
postcss-px-to-viewport
默认开启了 autoprefixer
常用
在 PostCSS 这个平台上,我们能够开发一些插件,来处理我们的CSS
我们能够使用JavaScript来开发插件
PostCSS
postcss-loader
.env.production文件比.env文件拥有更高的优先级
在package.json的script中存在的mode有最高优先级,不会被.env文件覆盖
Vue CLI 启动时已经存在的环境变量拥有最高优先级,并不会被 .env 文件覆写
环境文件发生变化,你需要重启服务
模式和环境变量
应用模式
库模式
构建目标
publicPath
注意
将 dist 目录里构建的内容部署到任何静态文件服务器中
具体操作
部署
process.env.BASE_URL引用的值就是publicPath
configureWebpack对象将会被 webpack-merge 合并入最终的 webpack 配置
configureWebpack属性
chainWebpack属性
ChainedMap
ChainedSet
webpack-chain
用相关的插件语法来修改具体配置
调整配置
审查项目配置
webpack 相关
vue.config.js
开发
vue-cli3+
core-js
regenerator-runtime
引入方式
独立出去变成npm包就是babel-polyfill插件
@babel/polyfill
项目部署在根目录下
当项目迁移到二级目录下时会访问不到
/
使用相对路径,更灵活
webpack打包时,从js文件中抽离了css和Img模块
当css没有抽离出来时,原相对路径可以访问到图片。但是抽离后会多了一层css文件夹
css文件里的背景图片访问不到
在style-loader里强制修改路径../../
vuecli4没有这个问题,内部已经优化了
./
/my-app/
assetsPublicPath
vue-cli2
jest.config.js
Wrapper
Vue Test Utils
Vue-Test-Utils + Jest
单元测试
根据后端接口文档,生成随机数据,拦截ajax请求
数据都是动态生成的假数据,无法真实模拟增删改查的情况
只支持 ajax,不支持 fetch
Mockjs
Mock
Eslint
我们直接写出来的源码模块是 module
webpack 处理时是 chunk
最后生成浏览器可以直接运行的 bundle
module、chunk、bundle
entry 里面列出的文件,经过webpack 打包后的输出文件名
filename
懒加载的chunk代码
没有显示指定时,使用id号来取名
未列在 entry 中,却又需要被打包出来的文件的名称
chunkFilename
filename、chunkFilename
以注释的形式为懒加载的文件取别名
webpackChunkName
在父 chunk 加载时并行下载文件
webpackPreload
在浏览器闲置下载文件
webpackPrefetch
webpackChunkName、webpackPreload、webpackPrefetch
与整个项目的构建相关,每打一次包更新一次
hash
与同一 chunk 内容相关
chunkhash
与文件内容本身相关
contenthash
哈希
配置项差别
开发模式,打包更加快速,省了代码优化步骤
development
生产模式,打包比较慢,会开启 tree-shaking 和 压缩代码
production
none
值
mode
输出文件名
filename属性
输出文件目录
当前文件(你用node运行的文件)所在的文件夹地址
__dirname
当前文件的完整地址(精确到你所运行的那个js文件)
__filename
path属性
output对象
loader下载后在module.rules属性中配置
webpack只支持js类型进行编译,Loader 就是将 Webpack 不认识的内容转化为认识的内容
style-loader
less-loader
sass-loader
常用css
img-loader
img font
babel-loader
json-loader
ts-loader
js
loader
下载后在plugin属性中配置
监听 webpack 的生命周期,在对应的生命周期进行特殊处理
html-webpack-plugin
clean-webpack-plugin
mini-css-extract-plugin
常用plugin
Plugin
Source Map
devtool
Hash
核心
配置项
/node_modules目录中用到的模块
chunk-vendors.js
entry字段
动态导入
基于SplitChunksPlugin插件实现
optimization.minimizer
webpack分包(trunks)方式
输出的文件
配置
有些 Loader 或者 Plugin 新版本会不兼容,需要进行降级处理
speed-measure-webpack-plugin
构建费时分析
resolve.alias
高频文件后缀名放前面
手动配置后,默认配置会被覆盖,如果想保留默认配置,可以用 ... 扩展运算符代表默认配置
resolve.extensions
resolve.modules
优化resolve属性里的配置
externals属性
include
exclude(优先级更高)
配置 loader时缩小范围
noParse属性
thread-loader
多进程配置
hard-source-webpack-plugin
插件实现
babel-loader 开启缓存
其他loader使用cache-loader
loader实现
cache属性实现
缓存
优化构建速度
webpack-bundle-analyzer
optimize-css-assets-webpack-plugin
压缩 CSS
terser-webpack-plugin
压缩 JS
purgecss-webpack-plugin
清除无用CSS
optimization属性
如果有些模块没有副作用需要在package.json设置sideEffects: false
Side Effect
Tree-shaking
优化构建结果
入口点分割
模块在代码中被复用或者来自 node_modules 文件夹
模块的体积大于等于30kb(压缩之前)
当按需加载 chunks 时,并行请求chunk的最大数量不能超过5
初始页面加载时,并行请求chunk的最大数量不能超过将3
默认配置
只选取异步加载的chunk进行代码拆分
只选取非异步加载的初始 chunk(入口文件)
initial
all
splitChunks.chunks
splitChunks.maxInitialRequests
splitChunks.maxAsyncRequests
splitChunks.minChunks
splitChunks.cacheGroups
optimization.splitChunks
代码懒加载
prefetch 与 preload
优化运行时体验
页面刷新,不保留页面状态
模块热替换
页面刷新分类
webpack-dev-server
实现
负责启动服务和前置准备工作
webpack-dev-server启动本地服务
与websoket有关
webpack-dev-server/client/index.js
webpack/hot/dev-server.js
修改webpack.config.js的entry配置
当监听到webpack编译结束,就会调用_sendStats方法
调用setupHooks方法
本地文件的编译和输出以及监听
webpack-dev-middleware
webpack监听源文件的变化
浏览器接收到热更新的通知
ajax请求
hotDownloadManifest
JSONP获取的代码可以直接执行
jsonp请求
hotDownloadUpdateChunk
moudle.hot.check 开始热更新
hotUpdateDownloaded热更新模块替换
HotModuleReplacementPlugin
HMR
plugin 的作用是监听 webpack 的生命周期,在对应的生命周期进行相应的处理
plugin是个类,需要提供一个apply方法,apply内接受compiler对象,compiler是webpack构建期间所生成的编译对象,可以通过监听compiler.hooks.xxx.tap 或者tapAsync,来实现插件,其中还有一个重要的对象是compilation,而compilation是webpack每次产生新的构建就会生成的一个对象,其中compiler在整个构建期间只会有一个,而compilation会有多个。
compiler和compilation都继承于tapable,而tapable其实是类似于node的eventEmitter的一个库,插件主要就是通过compiler或者compilation对webpack的构建周期进行各种处理的一个方式。
SyncHook
SyncBailHook
SyncWaterfallHook
SyncLoopHook
同步
AsyncParallelHook
AsyncParallelBailHook
并行
AsyncSeriesHook
AsyncSeriesBailHook
AsyncSeriesWaterfallHook
串行
异步
当前函数有返回值,就停止执行
bail
调用时,值会传递给下一个函数
waterfall
当返回true表示继续循环,返回undefined结束循环
loop
类型
同步通过tap进行注册
异步通过tapAsync、tapPromise
注册方式
同步通过call进行调用
异步通过callAsync、promise
调用方式
遍历插件,判断 plugin 的 constructor.name 属性即可
如何检测xx插件是否存在
tapable
loader本质是个函数,每个loader都会拿到上一个loader所处理的结果,并在当前loader进行处理,然后并返回,传递给下一个loader。
只处理函数和顶层的import/export变量,不能把 引用进来的类 当中没用到的方法消除掉
ES6模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析
ES6之前的模块化,比如我们可以动态require一个模块,只有执行后才知道引用的什么模块,这个就不能通过静态分析去做优化。
base
tree shaking
创建 Compiler 编译对象
初始化入口,解析入口文件,构建依赖树
确定编译环境
初始化内部解析
开始对文件进行编译
Compilation 会对依赖树的模块进行编译,可以在编译期间被加载、封存、优化、分块、重新创建
对每个模块创建Compilation
编译结束
输出文件
编译完成
编译流程
webpack
把 JavaScript 中 es2015/2016/2017/2046 的新语法转化为 es5,让低端运行环境(如浏览器和 node )能够认识并执行。
简介
使用单体文件
cli 就是命令行工具。安装了 babel-cli 就能够在命令行中使用 babel 命令来编译文件。
package.json 中的 scripts 段落中的某条命令
使用场景
把 babel-cli 安装为 devDependencies
在 package.json 中添加 scripts (比如 prepublish),使用 babel 命令编译文件
npm publish
执行步骤
这样既可以使用较新规范的 JS 语法编写源码,同时又能支持旧版环境。因为项目可能不太大,用不到构建工具 (webpack 或者 rollup),于是在发布之前用 babel-cli 进行处理。
在 node 环境中,直接运行 es2015 的代码,而不需要额外进行转码
babel-node = babel-polyfill + babel-register
对 require 命令加载的文件转码
只会对 require 命令加载的文件转码,而不会对当前文件转码。
实时转码,所以 只适合在开发环境使用
babel-register
babel 默认只转换 js 语法,而不转换新的 API
背景
把 babel-polyfill 作为 dependencies 而不是 devDependencies
提示
使用 babel-polyfill 会导致打出来的包非常大
babel-polyfill 会污染全局变量,给很多类的原型链上都作了修改
使用方法
优化babel转换的语法,将重复定义新变量变成了重复引用babel-runtime里的新方法和特性,精简代码
babel-plugin-transform-runtime
新方法、新特性的集合处
作为 core-js 的拾遗补漏,主要是 generator/yield 和 async/await 两组的支持。当代码中有使用 generators/async 时自动引入。
包含
需要安装为依赖,而不是开发依赖
babel-runtime
使用 babel-plugin-transform-runtime
cli3使用版本为2
cli4使用版本为3
要注意corejs的版本
core-js@3升级之后弃用了@babel/polyfill,变成了分别引入两个子包
babel7.4版本不支持babel-polyfill
babel-polyfill
babel-node
babel-cli
CLI(command-line interface,命令行界面)
一些大型的项目都会有构建工具 (如 webpack 或 rollup) 来进行代码构建和压缩 (uglify),在 uglify 之前就加入 babel 处理
babel-loader 也会读取 .babelrc 或者 package.json 中的 babel 段作为自己的配置,之后的内核处理也是相同。唯一比 babel-cli 复杂的是,它需要和 webpack 交互,因此需要在 webpack 这边进行配置。
执行方式
rollup-plugin-babel
构建工具的插件
三种方式只有入口不同而已,调用的 babel 内核,处理方式都是一样
使用babel的方式
能使得babel解析更多js语法
语法插件
把源码转换并输出
转译插件
生成
运行方式
同一类语法可能同时存在语法插件版本和转译插件版本。如果我们使用了转译插件,就不用再使用语法插件了。
plugin分类
官方内容
stage-x
preset
例如目标浏览器支持 es2015,那么 es2015 这个 preset 其实是不需要
如果不写任何配置项,env 等价于 latest,也等价于 es2015 + es2016 + es2017 三个相加
通过配置得知目标环境的特点,然后只做必要的转换。
核心目的
env
将插件的名字增加到配置文件中
使用 npm install babel-plugin-xxx 进行安装
使用方式
内部从左到右顺序执行
plugin
内部从右到左
babel
引用路径问题
Gulp
微内核架构
this.$router.push
this.$router.replace
router
router.routes
在路径中表现
$route.params
query表现在url里的查询字符串
$route.query
route
使用H5的pushState()和replaceState()方法
History
模式
动态路由匹配
router.routes中定义子路由(嵌套子路由)
组件内<router-view/>的使用
前提
监听$route
导航守卫
造成组件的生命周期钩子不会再被调用
组件复用
嵌套路由
单组件多视图
path和params是不能同时生效的
编程式导航
router.routes数组项的redirect属性
重定向
router.routes数组项的alias属性
别名
路由懒加载
router.scrollBehavior
滚动行为
vue-router
存储数据的公共容器
this.$store.state.全局数据名称
mapState辅助函数
访问
State
对Store中的数据进行加工处理,形成的新数据
this.$store.getters.Getters方法名
mapGetters辅助函数
Getter
用于变更Store中的数据
传入参数
this.$store.commit('Mutation的方法名')
mapMutations辅助函数
Mutation
Action 提交的是 mutation,而不是直接变更状态
Action 可以包含任意异步操作
this.$store.dispatch('action方法名')
mapActions辅助函数
Action
store.modules属性
vuex
基础工具
包含的工具
vue-cli
工具
工程化-基础建设
GET /home HTTP/1.1
/home
路径
HTTP/1.1
http版本
请求报文
HTTP/1.1 200 OK
OK
响应报文
起始行
Cache-Control
通用头部字段
请求头部专属字段
相应头部专属字段
头部
区分开头部和实体
空行
请求体
响应体
实体
报文结构
浏览器的原生 <form> 表单,如果不设置 enctype 属性时的默认值
介绍
经过 URL 编码的数据
用qs库来处理
生成请求体
浏览器的原生 <form> 表单,必须让 <form> 表单的 enctype 等于 multipart/form-data
用于图片等文件的上传,不用application/x-www-form-urlencoded,因为没有必要做 URL 编码
--boundary
内容描述信息
字段具体内容(文本或二进制)
如果请求体是FormData的实例,Content-Type自动转成multipart/form-data
通过FormData对象生成的实例,
消息主体是序列化后的 JSON 字符串
application/json
text/xml
根据头部字段Content-Type划分
GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
参数
GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制
编码
GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会
GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
请求次数
get post区别
在头部的Content-Type字段中标识
发送端
Accept字段中标识想要收到特定类型的数据
接收端
http从MIME type标准中取了一部分来标记报文 body 部分的数据类型,具体为特定字段的值
text/html
text/css
text
image/gif
image/jpeg
image/png
image
取值
数据格式
在头部的Content-Encoding字段中标识
Accept-Encoding字段中标识想要收到特定类型的数据
gzip
deflate
br
压缩方式
支持语言
Content-Type: text/html; charset=utf-8
Content-Type中的charset属性
Accept-Charset: charset=utf-8
Accept-Charset字段
字符集
Accept 系列字段
浏览器preloader机制加载的资源
<link rel=\"preload\">加载的资源
memory cache来源的分类
失效机制
浏览器会忽视http头部配置。直接读取memory cache
匹配完全相同的 URL 之外,还会比对他们的类型,CORS 中的域名规则等
不受开发者控制
读取机制
memory cache
memory cache没有对应资源时,会从dist cache中寻找。
disk cache 会严格根据 HTTP 头信息中的各类字段来判定哪些资源可以缓存
在响应消息头中
HTTP 1.0 的字段
来源
用户可能会将客户端本地的时间进行修改,而导致浏览器判断缓存失效,重新请求该资源
写法太复杂
Expires
表示n秒内可以读取该缓存
max-age
如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效
must-revalidate
可以在客户端存储资源
不对本次请求进行限制
no-cache
彻底得禁用缓存,本地和代理服务器都不缓存,每次都从服务器获取
no-store
可以被服务器和中间服务器缓存
public
所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值
private
字段里的常用属性值
字段值可以混合使用
HTTP/1.1的字段,一个相对时间
http头部有关字段名
Cache-control 的优先级高于 Expires
超过规定时间,强制缓存失效
执行机制
强制缓存直接减少请求数,是提升最大的缓存策略
优点
强缓存
减少响应体体积,缩短传输时间。
响应报文头部有Last-Modified字段
将这个值和内容一起记录在缓存数据库中
强缓存失效后,在请求头中的 If-Modified-Since 字段里放Last-Modified 的值
将请求头 If-Modified-Since 字段的值与服务器的 Last-Modified 字段进行对比
如果相等,则表示未修改,响应 304;反之,则表示修改了,响应 200 状态码,并返回数据。
流程
如果文件是通过服务器动态生成的,会出现文件内容可能没有变化,但是更新时间变了。起不到缓存的作用
资源更新的速度是秒以下单位,那么该缓存是不能被使用
只能精确到秒级
Last-Modified & If-Modified-Since
响应报文头部有Etag
请求相同资源时在请求头中的If-None-Match 字段里放Etag的值
服务器会将 If-Modified-Since 的值与 Last-Modified 字段进行对比。如果相等,则表示未修改,响应 304;反之,则表示修改了,响应 200 状态码,并返回数据。
Etag & If-None-Match
http中的字段名
协商缓存
disk cache
缓存是永久性的,即关闭 TAB 或者浏览器,下次打开依然还在
service worker
按缓存位置分类
http缓存
1xx - 服务器收到请求。
200 - 成功。
2xx - 请求成功
301 - 永久重定向(配合 location,浏览器自动处理)。
302 - 临时重定向(配合 location,浏览器自动处理)。
304 - 资源未被修改。
3xx - 重定向
403 - 没权限。
404 - 资源未找到。
4xx - 客户端错误
500 - 服务器错误。
504 - 网关超时。
5xx - 服务端错误
长连接的场景中,需要保存大量的上下文信息
http是一个不保存状态的协议,即一个服务器是不清楚是不是同一个浏览器在访问他
即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录
服务器发送到 Web 浏览器的一小块数据
当服务器返回带有Set-Cookie 标头时,此标头告诉客户端存储 Cookie
随着对服务器的每个新请求,浏览器将使用 Cookie 头将所有以前存储的 Cookie 发送回服务器
创建 Cookie
没有指定Expires或 Max-Age 指令
会话 Cookies
永久性 Cookie 不会在客户端关闭时过期,而是在特定日期(Expires)或特定时间长度(Max-Age)外过期
永久性 Cookies
浏览器将禁止页面的Javascript 访问带有 HttpOnly 属性的Cookie
HttpOnly
标识指定了哪些域名可以接受 Cookie
Domain
Path
name
value
Expires/Max-Age
document.cookie可以对cookie进行读写
访问cookie
cookie
在同一个会话期间,服务端会为这次请求开辟一块内存空间对象,存储客户端的一些操作记录这个对象便是 Session 对象,存储结构为 ConcurrentHashMap。
1、服务器第一次接收到请求时,生成一个 sessionId,并设置响应头 **Set-Cookie:JSESSIONID=XXXXXXX **
2、客户端在本机客户端设置了一个 **JSESSIONID=XXXXXXX **的 Cookie 信息
3、该 Cookie 的过期时间为浏览器会话结束
步骤
判断是否是同一会话
A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。
Session
无状态
明文传输
当 http 开启长连接时,共用一个 TCP 连接,同一时刻只能处理一个请求,那么当前请求耗时过长的情况下,其它的请求只能处于阻塞状态
队头阻塞问题
WebSocket协议
轮询
通信只能由客户端发起
文本
图片
视频
传输形式的多样性
没有严格的语法限制
灵活可扩展
可靠传输
每次 http 请求都是独立、无关的,默认不需要保留状态信息
一发一收、有来有回
请求-应答
短链接不占服务器的内存 服务器能处理的连接数量会比较多
短连接优点
不能做到发送消息的实时性。
耗费大量的CPU和网络带宽资源
短连接缺点
默认的连接是短链接
http1.0
保证数据收发的实时性
长连接优点
系统资源可能就不够了
并发连接
域名分片
http1.1解决方案
http的对头阻塞问题
长连接缺点
TCP长连接
本质
默认的连接都是长连接
http1.1
使用HPACK 算法
头部字段压缩
HTTP 基于请求-响应的模型
在同一个 TCP 长连接中,客户端每次发送一个请求到服务端,服务端返回响应。
前面的http请求没有得到响应,后面的http请求就会被阻塞
HTTP 队头阻塞
优化的原因
HTTP/2 用流来在一个 TCP 连接上来进行多个数据帧的通信
二进制帧序列
流(Stream)
Headers帧存放头部字段
Data帧存放请求体数据
Headers + Body的报文拆分成二进制的帧
发送前的准备
不同 ID 的 Stream 是乱序的,但同一个 Stream ID 的帧一定是按顺序传输的
通过流来传输
发送中
服务器看到的不再是一个个完整的 HTTP 请求报文,而是一堆乱序的二进制帧。
不同 ID 的 Stream 是乱序的,但同一个 Stream ID 的帧一定是按顺序传输
二进制帧到达后对方会将 Stream ID 相同的二进制帧组装成完整的请求报文和响应报文
接收
二进制分帧
实现方案
多路复用
优化点
http2.0
TLS1.2
强化安全
握手改进
会话复用
提高性能
TLS 1.3
HTTPS = HTTP + SSL/TLS
http协议
可以发送文本,也可以发送二进制数据
没有同源限制
协议标识符是ws(如果加密,则为wss)
在网页脚本里
baseURL的值将自动加在请求url前,除非url是一个绝对URL
baseURL
axios
常用插件
XHR对象
AJAX
请求交互
是指恶意攻击者往Web页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的
点击一个恶意链接
提交一个表单
把黑客输入的数据 “反射” 给浏览器
反射型(持久形)
在评论区写下包含恶意 JavaScript 代码的评论
把黑客输入的数据 \"存储\" 在服务器端
存储型(非持久形)
通过恶意脚本修改页面的 DOM 结构
DOM型
通过xx方式,恶意注入代码,然后被执行
攻击方式
对输入内容进行校验,并对一些字符做转义处理
能阻止 XSS 攻击后的 Cookie 劫持攻击
防御
XSS
检查 http 的 Referer 字段,判断是否同域名下
验证码
CSRF
Web安全
前端知识体系
0 条评论
回复 删除
下一页