前端知识点
2022-03-17 16:46:09 36 举报
AI智能生成
为你推荐
查看更多
根据面试题整理的知识点
作者其他创作
大纲/内容
外层包template标签
计算属性把不需要的数据过滤
vue2.x v-for 比 v-if 优先级高
vue3.x v-if 比v-for 优先级高
节点的删除创建
代码不常用时用 v-if
v-if
display: none隐藏,保留DOM节点
代码常用时用 v-show
v-show
1. v-if 与 v-for 与 v-show
1. 单页面每一次页面的跳转,是通过JS把当前页面数据删除,然后渲染新页面的DOM结构
2. 跳转仅刷新局部资源 ,公共资源(js、css等)仅需加载一次
1. 首屏时间稍慢(需要进行一个html请求和JS请求,两个都返回才能展示)
2. SEO差(搜索引擎只认识html中的内容,不认识js中的内容)
缺点:
页面切换快
优点:
单页面
1. 每一次页面的跳转,客户端都会返回一个新的html
2. 跳转刷新所有资源,每个公共资源(js、css等)需选择性重新加载
页面切换慢
1. 首屏时间快(首个屏幕展现出来的时间),因为只经历过一个http请求,请求回来了,页面就展示出来了
2. SEO(搜索引擎优化)效果好
优点
多页面
2. 单页面应用和多页面应用区别及优缺点?
DOM操作很慢,轻微操作都有可能导致页面的重排和重绘,相当于DOM对象,js对象处理起来更快,而且更简单。通过diff算法对比新旧vdom之间的差异
why?
3. 虚拟DOM
数据响应式:一种为了驱动数据和视图更新的机制
为了数据驱动,使操作的数据影响到视图层的更新
为什么需要数据响应式?
1. 核心 Object.defineProperty
遍历定义的 props 配置
一个是调用 defineReactive 方法把每个 prop 对应的值变成响应式可以通过 vm._props.xxx 访问到定义 props 中对应的属性另一个是通过 proxy 把 vm._props.xxx 的访问代理到 vm.xxx 上
遍历
1. 校验是否为函数,2. 与props重名校验,3. 是否以$或_开头
将函数绑定到 vm 上
1. 先判断 data 是 function 还是 object, function 就会直接生成一个新对象,object 则会直接赋值
2. 遍历,与props和methods进行命名检测,不冲突则调用proxy方法,使之可以用vm(this) 访问
3> initData(vm)
1. 遍历,为每个属性添加watcher
2. 判断是否在vm上,不存在则绑定到vm上
1. 循环遍历调用 createWatcher 进行绑定监听
2. createWatcher 里面使用 vm.$watch
2. 初始化会走 initState(vm) 方法
initProps
initData
initMethods
initComputed
initWatch
简写:通过 Object.defineProperty 把 target[sourceKey][key] 的读写变成了对 target[key] 的读写
1> proxy
2. 如果当前是响应式对象这直接返回该响应式对象(__ob__)
3. 不是则 new Observer 进行响应式监听
4. 返回ob(Observer类会为每一个对象添加'__ob__'属性,所以可以来判断他是否有子对象)
2> observe
2. 调用 def 方法为当前对象添加 '__ob__' 属性
3. 判断是否为数组,数组则遍历每一项并调用 observe () 方法进行数组每一项判断 并且改变其数组的原型指向,指向到新设置的响应式原型(重写的监听数组方法的原型)
4. 对象则直接调用 walk 方法进行每一项调用defineReactive进行响应式监听
3> class Observer 类
1. const dep = new Dep() 此时一个key对应一个dep
2. 调用 observe(val) 方法 返回 childOb,对象则返回Observer实例,否则undefined 同时该方法内如果是对象则递归进行 new Observer ,进行响应式绑定,疯狂套娃
dep.depend() (dep 和 当前watcher 互相添加映射关系)
childOb ? childOb.dep.depend() (子ob实例也要添加映射关系)
Array.isArray(value) ? dependArray(value) (如果value值为数组,也需递归遍历添加映射关系(防止数组里面存储的是值类型))
get
判断新值老值是否一样
设置最新的值
observe(newVal) 对新值进行响应式处理
dep.notify() 通知更新
set
3. Object.defineProperty 进行响应式绑定
4> defineReactive
3. 扩展函数
proxy
observe
Observer 类
参考:Vue解析文档
4. Vue2.x 响应式原理
initSate
5. Vue3.x 响应式原理
1. 优先级 render > template > el
2. 没有render 的时候会调用 compileToFunctions 来根据 template 生成 render 函数
3. compileToFunctions 是最里面的一层,通过了究极闭包,最终会调用 baseCompile 方法,该方法又会调用 parseHTML方法生成AST树,parseHTML是JQuery作者写的
4. 该扩展方法最终就调用原生的$mount方法
1. 扩展mount方法,主要作用是生成render方法src\\platforms\\web\\entry-runtime-with-compiler.js
patch是通过createPatchFunction函数创建的
mountComponent 方法内容
2. 定义 updateComponent 组件更新函数
子主题
3. new Watcher() 进行当前组件的watcher 初始化初始化结束后会立即执行一遍传入的组件更新函数
mount 方法里面会调用 mountComponent 方法执行挂载
2. 原型上定义patch和$mount方法src\\platforms\\web\untime\\index.js
初始化全局API component/directive/filter/use/mixin/set/dellete/extend
3. initGlobalAPI(Vue)src\\core\\index.js
1. function Vue (options) {}
_init 内容
1. 选项合并:当前选项和全局选项进行合并
2. initLifecycle(vm) // - 初始化 $parent/$root/$children/$refs
3. initEvents(vm) // - 自定义事件的监听 $on/$off
4. initRender(vm) // - 初始化 $slots/$scopedSlots/_c/$createElement/$attrs/$listeners
6. initInjections(vm) // - 数据响应式监听 resolve injections before data/props
7. initState(vm) // - 初始化 props/methods/data/computed/watch ----- 依次优先级设置数据响应式
8. initProvide(vm) // - resolve provide after data/props
10 最后调用 vm.$mount(vm.$options.el)进行挂载
2. initMixin(Vue) // - _init
3. stateMixin(Vue) // - $set/$delete/$watch 初始化 $data/$props声明
4. eventsMixin(Vue) // - $emit/$on/$off/$once
5. lifecycleMixin(Vue) // - _update/$forceUpdate/$destroy
6. renderMixin(Vue) // - $nextTick/_render
4. Vue 构造函数声明 和 实例的属性、实例方法初始化src\\core\\instance\\index.js
Vue2.x 初始化过程
2. packages\untime-core\\src\\apiCreateApp.ts
3. packages\untime-core\\src\enderer.ts
createApp() => ensureRenderer() => createRenderer() => baseCreateRenderer() => reateAppAPI => mount() => render() => path() => processComponent() => mountComponent()
mountComponent => setupComponent() => setupStatefulComponent() => handleSetupResult() => finishComponentSetup()
1. const app = ensureRenderer().createApp(...args)先获取App实例
2. mount扩展:获取根元素的dom节点
1. 执行 packages\untime-dom\\src\\index.ts 导出的 creteApp 函数
ensureRender
2. ensureRenderer() 调用 createRenderer() 返回一个渲染器
createRenderer
3. createRenderer() 调用 baseCreateRenderer() 返回一个对象packages\untime-core\\src\enderer.ts
定义patch函数,用于根据不同的节点类型匹配不同的处理函数
1. cosnt patch = fn
定义render函数,进行patch比较
2. const render = fn
判断节点1. 初始组件挂载 调用 mounComponent()
2. 组件更新 调用 updateComponent()
3. const processComponent = fn
initSlots
调用 setupStatefulComponent() 进行数据处理
1. 调用 setupComponent 进行组件配置
组件更新函数instance.update = effect(function componentEffect() {})
2. 调用 setupRenderEffect 进行依赖收集
4. const mounComponent = fn
4. baseCreateRenderer()
概要
返回函数 createApp
5. createAppAPI()
1. 创建context上下文
1. use
2. mixin
3. component
4. directive
1. 调用 createVnode 获的 VNode
5. mount
6. unmount
7. provide
给实例对象 app 赋值实例方法
mount
6. createApp()
6. Vue3.x 初始化过程
createApp
createAppAPI
避免打包时把一些没有的代码加进去
1. Vue3.x 没有了静态方法,只有通过 createAPP 创建的实例方法(app.use/mixin/component/mount 例 Vue.use())
兼容性查询
proxy 兼容性
proxy 是劫持对象而不用递归劫持数据
2. 核心方法 Object.defineProperty变成 Proxy
3. 支持 Fragments,每个组件不需要一个根组件进行包裹,这样可以节省不必要的DOM结构
4. 数据响应式设置,以前在data里面的数据都会被响应式监听,但是现在只有自己设置的才会进行响应式监听,极大地降低了消耗成本
5. 所有代码都可以写在 setup 里面,相同的逻辑可以直接抽离出去,维护时不需要返回横跳
6. 算法优化:增加静态标记,Vue3采用二进制来标记节点类型,如diff是碰到静态节点类型的标记会直接跳过,而不需求深层次递归,优化性能
7. 增加 Teleport 标签,能够使指定内容挂载到指定dom节点下
8. 生命周期改变,去除 beforeCreate 和 created,增加 setup,其他的都加on,destroy 变成 Unmount
9. 没有watcher,用effect和使用到了响应式对象进行映射
7. Vue2.x 与 Vue3.x 的区别
teleport定义:把自己包裹的内容渲染在自己想要渲染的指定元素下如果在配合components使用的话,在做到根据自己需求指定渲染位置的体况下,依然跟组件保持父子组件关系,从而轻易的做到数据传递
内部默认使用 document.querySelector() 查询元素
可以多个teleport可以都指向同一标签,结果是按顺序添加
8. Vue3 中 Teleport 的作用是什么
0. 由于在执行 setup 时尚未创建组件实例,因此在 setup 选项中没有 this。这意味着,除了 props 之外,你将无法访问组件中声明的任何属性——本地状态、计算属性或方法
1. props 作为setup 的第一个参数返回,第二个参数是当前实例对象
2. 生命周期,watch,computed 都可以写在 setup 里面
代替 beforeCreate 和 created
setuo()
代替 beforeMount
onBeforeMount
代替 mounted
onMount
代替 beforeUpdate
onBeforeUpdate
代替 updated
onUpdated
代替 beforeDestroy
onBeforeUnmount
代替 destroyed
onUnmounted
代替 errorCaptured
onErrorCaptured
代替 renderTracked
onRenderTracked
代替 renderTriggered
onRenderTriggered
2. 生命周期
9. Vue3的composition api
1. v-model 默认向下传递的值从 value 变成 modelValue
2. v-model 默认向下传递的方法从 update 变成 update:modelValue
3. 可以更换 v-model 的默认参数,例:v-model:title=\"title\
4. 取消了.sync修饰符的使用
10. Vue3中v-model的变化有哪些?
Vue 遵循着 深度优先,所以优先子组件(从外到内再由内到外)
挂载阶段:父bc -> 父created -> 父bm -> 子bc -> 子created -> 子bm ->子mounted -> 父mounted
更新阶段:父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated(当父组件有数据 传递时才会触发)
销毁阶段:父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
相似问题:子组件的props与created()谁先触发?-》执行顺序beforeCreate ->inject -> Props -> Methods -> Data -> Computed -> Watch ->provide-> created
11. Vue父子组件生命周期谁先谁后
v-model
1. new 一个新的 Vue 对象
2. 利用其 $on(注册) 和 $emit(触发) 的特性来使用
bus总线
provide,injected
$refs
12. Vue组件通信
EventBus
计算属性,监听内部用到的响应式对象,当对象值改变时,就会执行改回调函数,所以也具有缓存效果
computed:
监听某一个响应式对象
该对象改变时,watch的回调也会改变,回调函数有两个参数,新值和旧值
watch 可以是函数或者对象
对象可以设置deep 和 immediate
watch:
13. computed 和 watch
使用parseHTML插件 栈
markStatic(root)
Vue 的模板编译原理(2和3差不多)
编译阶段优化
所有的静态节点全部放在render函数的外面
1. 静态提升
2. 补丁标记和动态属性记录
为了避免每次子节点变化
3. 缓存事件处理程序
createBlock
4. 块block
3.x 静态标记与优化
1. children 可以是数组或者文本
2. 新增 dynamicChildren 和 dynamicProps 用来存储动态属性和子节点
packages\\shared\\src\\patchFlags.ts
3. 新增 patcFlag 表示patch时应该比较什么内容
shared/src/shapeFlags.ts
4. 新增shapeFlag 表示当前组件的类型Teleport 或 Fragment
6. type 表示节点类型,不再是数字
Vue3 新的Vnode结构
1. 根据类型走不同的path函数
2. 判断patchFlag的值需不需要更新
1. 初始化 - 调用 mountChildren 进行子节点递归挂载(深度优先)
遍历 dynamicChildren 进行patch比较v-for遍历的节点不需要存放在dynamicChildren
是:调用 patchBlockChildren() 进行块级更新
1. 先获取新老数组最后一项的索引
2. while循环遍历,去除头部相同的节点
3. while循环遍历,去除尾部相同的节点
4. 判断是否需要新增
6. 判断是否需要删除
7. 乱序,新老各剩几个节点,则进行挨个查找比较
a b c da b e c d
有key: patchKeyedChildren()
无可以: patchUnkeyedChildren()
否:patchChildren() keyed / unkeyed
if ( patchFlag > 0 && patchFlag & PatchFlags.STABLE_FRAGMENT && dynamicChildren )
2. 更新
3. if (n1=== null)
2. 例:processFragment
Vue3 patch
Vue
teleport
定义:节省流量,将多次执行变成每隔一段时间执行。
节流
定义:防止抖动,多次执行变为最后一次执行
防抖
1. 节流和防抖分别是什么?在什么场景下使用?请分别实现一个节流函数和一个防抖函数
设置HttpOnly
当secure属性设置为true时,表示创建的 Cookie 会被以安全的形式向服务器传输,也就是只能在 HTTPS 连接中被浏览器传递到服务器端进行会话验证
设置secure属性
2. 怎么禁止让js读取cookie?怎么让cookie只在HTTPS下传输
3. 存储数据 什么样情况下用数组什么样情况下用对象
一种代码包代码的方式叫装饰器
在不改变对象自身的基础上,在程序运行期间给对象动态的添加职责
所以可以链式调用,俄罗斯套娃
4. 装饰器
1. 和Java里面一样,null是一个对象,所以 typeof null 为object
2. null 转数值 为 0
null
1. 新增的基本数据类型,typeof undefined 为 undefined
2. undefined 转数值 为 NaN
undefined
null == undeined true;null ===undefined false
语义:null 表示一个空对象,undefined 表示原始状态值
5. null 和 undefined的区别
JS
维护连接关系
连通性(传递性)问题
基础知识
集合连接操作
查找O1 连接On
1. 定义一个集合,存放不同颜色
2. 初始化时遍历数据,为每个数据给上指定颜色
3. 定义个查找方法,查找指定数据的颜色
实现
染色法(Quick-Find算法)
树形结构,节点连接
查找On 连接O1
1. 定义一个集合,存放当前点的父节点编号
2. 初始化时遍历数据,初始每个节点的父节点为自己(此时每个节点就相当于一个根节点)
3. find() 如果当前的父节点是自己,则直接返回自己,否则递归向上查找,直至找到根节点
极端情况下,最后是一个链表,所以查找的速度和树高有关
优化策略:按秩优化:平均查找次数 总查找次数/总节点数
find() 里面处理,找到根节点后,直接把当前节到根节点的所有节点都挂载到根节点上 f(x)= root
再次优化:路径压缩,减少中间商
优化
题目
力扣547-省市操作,200-岛屿数,990-等式方程的可满足性,684-冗余连接,1319-连通网络的操作次数,128-最长连续序列,947-移除最多的同行或同列石头,1202-交换字符串中的元素
练习
Quick-Union 算法
Quick-Union
并查集
Quick-Find
算法
定义:一个进程就是一个程序的运行实例。详细解释,启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程
进程
多线程可以并行处理任务,但是线程是不能单独存在的,它是由进程来启动和管理的,所以线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率
线程
1. 进程中的任意一线程执行出错,都会导致整个进程的崩溃
2. 线程之间共享进程中的数据
3. 当一个进程关闭之后,操作系统会回收进程所占用的内存
4. 进程之间的内容相互隔离
进程与线程的关系
所有功能都在一个进程里面执行
不稳定性
不流畅
不安全
早期单进程浏览器时代
早期多进程浏览器时代
浏览器多进程架构
主要负责界面显示、用户交互、子进程管理,同时提供存储等功能
浏览器进程:
渲染进程:
页面绘制,最初是绘制3D CSS效果
GPU 进程:
负责页面的网络资源加载
网络进程:
负责插件的运行,因为插件容易崩溃,所以为了防止插件的崩溃影响到页面,单独抽离出一个插件的进程出来
插件进程:
更高的资源占用因为每个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),这就意味着浏览器会消耗更多的内存资源。更复杂的体系架构浏览器各模块之间耦合性高、扩展性差等问题,会导致现在的架构已经很难适应新的需求了
目前多进程浏览器时代
未来面向服务架构(SOA)
浏览器时代
多进程浏览器架构
早期单进程时代
权限问题:一个进程使用了安全沙箱之后,该进程对于操作系统的权限就会受到限制,比如不能对一些位置的文件进行读写操作,而这些权限浏览器主进程所需要的,所以安全沙箱是不能应用到浏览器主进程之上的
1. 为什么单进程浏览器当时不可以采用安全沙箱?
2. 有插件的话,插件也会开启进程
3. 多个页面属于同一站点,并且从a打开b页面,会共用一个渲染进程
Chrome的默认策略是,每个标签对应一个渲染进程。但是如果从一个页面打开了新页面,而新页面和当前页面属于同一站点时,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫process-per-site-instance
所以当一个页面崩溃了,会导致同一个站点的其他页面也奔溃,这是因为它们使用的是同一个渲染进程
4. 装了扩展的话,扩展也会占用进程
2. 打开Chrome浏览器一个Tab页面,至少会出现几个进程?
3. 即使如今多进程架构,还是会碰到单页面卡死的最终崩溃导致所有页面崩溃的情况,讲一讲你的理解?
相关面试题
进程与线程
1. 构建请求
在真正发起网络请求之前,浏览器会先在浏览器缓存中查询是否有要请求的文件
当浏览器发现请求的资源已经在浏览器缓存中存有副本,它会拦截请求,返回该资源的副本,并直接结束请求,而不会再去源服务器重新下载
2. 查找缓存
因为浏览器使用 HTTP 协议作为应用层协议,用来封装请求的文本信息;并使用 TCP/IP 作传输层协议将它发到网络上,所以在 HTTP 工作开始之前,浏览器需要通过 TCP 与服务器建立连接。也就是说 HTTP 的内容是通过 TCP 的传输数据阶段来实现的
3. DNS服务器解析域名(准备好IP和端口)
Chrome 有个机制,同一个域名同时最多只能建立 6 个 TCP 连接,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。
4. 等待TCP队列
一个完整的TCP连接生命周期包括了“建立连接”“传输数据”和“断开连接”三个阶段
5. 建立TCP请求
6. 发起 HTTP 请求
7. 服务器处理请求
8. 服务器返回请求和断开连接
整体流程
HTTP请求流程
Cache-Control与Expires他们的作用是一样的,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据
Expries是http1.0的标准,在HTTP/1.1之后被Cache-Control替代 Cache-Control的选择更多,如果同时设置的话,其优先级高于Expires
Expries的设置方式
Cache-Control的设置方式
Public:指示响应可被任何缓存区缓存。Private:所有内容只有客户端可以缓存,也是Cache-Control的默认取值。no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存max-age:也就是刚刚上面例子中用到的,max-age=xxx :缓存内容将在xxx秒后失效。min-fresh:指示客户机可以接收响应时间小于当前时间加上指定时间的响应。max-stale:指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
Cache-Contro 的配置字段
规则:浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息)若命中直接从缓存中获取资源信息,包括缓存header信息,本次请求就不会与服务器进行通信
强缓存
规则:协商缓存最终由服务器来决定是否使用缓存,即客户端与服务器之间存在一次通信
控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match
其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高
协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的
协商缓存
http缓存
webStorage和cookie 以及indexDB
本地缓存
客户端缓存
不请求网络资源,资源在内存当中,一般脚本、字体、图片会存在内存当中
from memory:内存中的缓存
不请求网络资源,在磁盘当中,一般非脚本会存在内存当中,如css等
from disk:硬盘中的缓存
两者都是强缓存
1、先查找内存,如果内存中存在,从内存中加载;2、如果内存中未查找到,选择硬盘获取,如果硬盘中有,从硬盘中加载;3、如果硬盘中未查找到,那就进行网络请求;4、加载到的资源缓存到硬盘和内存;
三级缓存原理:
浏览器出现 from disk、from memory 的 策略是啥
1. 客户端缓存有几种方式?浏览器出现 from disk、from memory 的 策略是啥?
CORS:跨域资源共享,是一份浏览器技术的规范,用来避开浏览器的同源策略
Access-Control-Allow-Origin :指示请求的资源能共享给哪些域。 Access-Control-Allow-Credentials: 指示当请求的凭证标记为 true 时,是否响应该请求。 Access-Control-Allow-Headers: 用在对预请求的响应中,指示实际的请求中可以使用哪些 HTTP 头。 Access-Control-Allow-Methods :指定对预请求的响应中,哪些 HTTP 方法允许访问请求的资源。 Access-Control-Expose-Headers: 指示哪些 HTTP 头的名称能在响应中列出。 Access-Control-Max-Age :指示预请求的结果能被缓存多久。 Access-Control-Request-Headers: 用于发起一个预请求,告知服务器正式请求会使用那些 HTTP 头。 Access-Control-Request-Method: 用于发起一个预请求,告知服务器正式请求会使用哪一种 HTTP 请求方法。Origin :指示获取资源的请求是从什么域发起的。
CORS相关请求头设置
1. 看http请求方法:HEAD、GET、POST
其中Content-Typede的值只能是:application/x-www-form-urlencoded、multipart/form-data、text/plain
2. 看请求头:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type
3. 不会触发CORS预检的请求称为简单请求
简单请求:
只要不是简单请求那就是复杂请求
复杂请求表面上看起来和简单请求使用上差不多,但实际上浏览器发送了不止一个请求 其中最先发送的是一种\"预请求\",也就是options 此时作为服务端,也需要返回\"预回应\"作为响应, 预请求实际上是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行
复杂请求:
2. CORS 的简单请求和复杂请求的区别?
Token:访问资源的凭证 一般是用户通过用户名和密码登录成功之后,服务器将登陆凭证做数字签名,加密之后得到的字符串作为 token然后在用户登录成功之后会返回给客户端
将token存放在webStorage中的话,是可以通过同域的js来访问的 ,就会导致很容易受到xss攻击,特别是项目中引入很多 第三方js类库的情况下,如果js脚本被盗用,那攻击者就 可以轻易访问你的网站,webStorage作为一种储存机制,在传输过程中是不会执行任何安全标准的
如果是将token存放在cookie中,我们可以指定 httponly,来防止被Javascript读取,也可以指定secure,来保证token只在HTTPS下传输,缺点是不符合Restful 最佳实践,容易受到CSRF攻击
XSS攻击:cross-site Scripting 跨站脚本攻击这是一种注入代码攻击 恶意攻击者在目标网站上注入script代码,当访问者浏览网站的时候通过执行注入的script代码达到窃取用户信息,盗用用户身份等
CSRF跨站点请求伪造(Cross—Site Request Forgery)利用用户已登录的身份,在用户毫不知情的情况下,以用户的名义完成非法操作
3. Token 一般是存放在哪里? Token 放在 cookie 和放在localStorage、sessionStorage 中有什么不同?
定义:webSocket是一种全双工通信协议,让服务端和客户端通信变得简单 最大的特点是可以通过服务端主动推送消息到客户端
广播通信需要对于非自身的所有连接的socket对象进行通信
点对点通信,通过关联用户及socket对象,且保存每一个socket连接 查找指定的socket对象来达到发送指定socket连接的目的
WebSocket 区分广播通信及点对点通信核心在于区分每一个连接的socket对象
4. WebSocket 是怎么实现点对点通信和广播通信的?
5. 浏览器的组成
1. 浏览器进程发出URL请求给网络进程
2. 网络进程接收到URL请求后,发起网络请求,然后服务器返回HTTP数据到网络进程,网络进程解析HTTP响应头数据,并将其转发给浏览器进程
3. 浏览器进程接收到网络进程的响应头数据后,发送CommitNavigation消息到渲染进程,发送CommitNavigation时会携带响应头、等基本信息。
4. 渲染进程接收到CommitNavigation消息之后,便开始准备接收HTML数据,接收数据的方式是直接和网络进程建立数据管道
5. 最后渲染进程会像浏览器进程“确认提交”,这是告诉浏览器进程,说我已经准备好接受和解析页面数据了
6. 最后浏览器进程更新页面状态
浏览器会根据用户输入的信息判断是搜索还是网址,如果是搜索内容,就将搜索内容+默认搜索引擎合成新的URL;如果用户输入的内容符合URL规则,浏览器就会根据URL协议,在这段内容上加上协议合成合法的URL
用户输入完内容,按下回车键,浏览器导航栏显示loading状态,但是页面还是呈现前一个页面,这是因为新页面的响应数据还没有获得。
1. 用户输入URL
浏览器进程将构建请求行数据,然后IPC(进程间通信)将URL请求发送给网络进程
2. URL 请求过程
3. 网络进程获取到URL,先去本地缓存中查找是否有缓存文件,如果有,拦截请求,直接200返回;否则,进入网络请求过程
4. 网络进程请求DNS返回域名对应的IP和端口号,如果之前DNS数据缓存服务缓存过当前域名信息,就会直接返回缓存信息;否则,发起请求获取根据域名解析出来的IP和端口号,如果没有端口号,http默认80,https默认443。如果是https请求,还需要建立TLS连接
5. 在进程TCP连接的过程中,Chrome有个机制,同一个域名下最多只能建立6个TCP连接,如果在同一个域名下有10个请求发生,那么其中4个请求会进入等待转台,直至进行中的请求完成。如果请求个数小于6,会直接建立TCP连接
6. TCP三次握手建立连接,http请求加上TCP头部——包括源端口号、目的程序端口号和用于校验数据完整性的序号,向下传输。
7. 网络层在数据包上加上IP头部——包括源IP地址和目的IP地址,继续向下传输到底层
8. 底层通过物理网络传输给目的服务器主机,紧接着目的服务器主机网络层接收到数据包,解析出IP头部,识别出数据部分,将解开的数据包向上传输到传输层
9. 目的服务器主机传输层获取到数据包,解析出TCP头部,识别端口,将解开的数据包向上传输到应用层
10. 应用层HTTP解析请求头和请求体,如果需要重定向,HTTP直接返回HTTP响应数据的状态code301或者302,同时在请求头的Location字段中附上重定向地址,浏览器会根据code和Location进行重定向操作;如果不是重定向,首先服务器会根据 请求头中的If-None-Match 的值来判断请求的资源是否被更新,如果没有更新,就返回304状态码,相当于告诉浏览器之前的缓存还可以使用,就不返回新数据了;否则,返回新数据,200的状态码,并且如果想要浏览器缓存数据的话,就在相应头中加入字段 Cache-Control:Max-age=2000
11. 数据传输完成,TCP四次挥手断开连接。如果,浏览器或者服务器在HTTP头部加上如下信息,TCP就一直保持连接。保持TCP连接可以省下下次需要建立连接的时间,提示资源加载速度数据传输完成,TCP四次挥手断开连接。如果,浏览器或者服务器在HTTP头部加上Connection:Keep-Alive,TCP就一直保持连接。保持TCP连接可以省下下次需要建立连接的时间,提示资源加载速度
Content-Type 的值是 application/octet-stream,显示数据是字节流类型的
text/html 页面
12. 网络进程将获取到的数据包进行解析,根据响应头中的Content-type来判断响应数据的类型,如果是字节流类型,就将该请求交给下载管理器;如果是text/html类型,就通知浏览器进程获取到文档准备渲染
13. 浏览器进程获取到通知,根据当前页面B是否是从页面A打开的并且和页面A是否是同一个站点(根域名和协议一样就被认为是同一个站点),如果满足上述条件,就复用之前网页的进程,否则,新创建一个单独的渲染进程
14. 浏览器会发出“提交文档”的消息给渲染进程,渲染进程收到消息后,会和网络进程建立传输数据的“管道”,文档数据传输完成后,渲染进程会返回“确认提交”的消息给浏览器进程浏览器会发出“提交文档”的消息给渲染进程,渲染进程收到消息后,会和网络进程建立传输数据的“管道”,文档数据传输完成后,渲染进程会返回“确认提交”的消息给浏览器进程
15. 浏览器收到“确认提交”的消息后,会更新浏览器的页面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新web页面,此时的web页面是空白页
16. 渲染进程对文档进行页面解析和子资源加载,HTML 通过HTM 解析器转成DOM Tree,CSS按照CSS 规则和CSS解释器转成CSSOM TREE,两个tree结合,形成render tree(不包含HTML的具体元素和元素要画的具体位置),通过Layout可以计算出每个元素具体的宽高颜色位置,结合起来,开始绘制,最后显示在屏幕中新页面显示出来
详细流程
6. 从输入URL到页面展示,这中间发生了什么
1. 先将 HTML解析成一个DOM树
从右往左读取选择器
为什么 id选择器大于类选择器,类选择器大于元素选择器?匹配的选项由少到多
2. 将 CSS解析成 CSS Rule Tree
3. 根据DOM树和CSS规则来构造 Rendering Tree
4. 然后进入布局(Layout)。计算节点在页面上的位置
5. GPU 绘制
解析器遇到 script标记时立即解析并执行脚本。文档的解析将停止,直到脚本执行完毕
span style=\
标注为“defer”的script不会停止文档解析,而是等到解析结束才执行
标注为“async”只能引用外部脚本,下载完马上执行,而且不能保证加载顺序
所以为了用户体验,后来有了async和defer,将脚本标记为异步,不会阻塞其他线程解析和执行。
6. js解析
7. 浏览器如何渲染UI
重绘不一定会引起重排,重排会引起重绘
重排:部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素
重绘:由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变
添加、删除、更新DOM节点
通过display: none隐藏一个DOM节点-触发重排和重绘
通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
移动或者给页面中的DOM节点添加动画
添加一个样式表,调整样式属性
用户行为,例如调整窗口大小,改变字号,或者滚动。
如何触发重排和重绘?
通过改变class的方式来集中改变样式
通过createDocumentFragment创建一个文档碎片,然后在此节点上批量操作,最后插入DOM树中,因此只触发一次重排
提升为合成层
如何避免重绘或者重排?
8. 重排和重绘
安全机制,指\"协议+域名+端口\"三者相同
浏览器中的大部分内容都是受同源策略限制的,但是 img,link,script三个标签不受限制
11道浏览器原理面试题
同源策略
jsonp
cors
Nginx 反向代理
WebSocke
window.name + iframe
location.hash + iframe
document.domain + iframe
postMessage
Node中间件代理(两次跨域)
跨域的实现方式
跨域
9. 同源策略,跨域
定义:Websocket是一个全新的、独立的协议,基于TCP协议,与http协议兼容
优点:真正意义上的实时双向通信,性能好,低延迟
缺点:独立与http的协议,因此需要额外的项目改造,使用复杂度高,必须引入成熟的库,无法兼容低版本浏览器
10 WebSocket
作用:就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行
1. 主线程与Worker线程通过方法postMessage相互传递信息
2. 主线程与Worker线程通过事件onmessage接收相互传递的消息
4. 主线程调用worker.terminate()结束线程
5. Worker线程通过调用this.close()结束自身线程
11 Web Worker
又称长链接,就是能在多次 HTTP 之间重用同一个 TCP 连接,从而减少创建/关闭多个 TCP 连接的开销
http 1.0中默认是关闭的,需要在http头加入\"Connection: Keep-Alive\"
目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了
12 HTTP keep-alive
1. 数据在URL中,URL的长度最多为2048个字符(浏览器的限制,不是HTTP)
2. 可被缓存
3. 请求参数保留在浏览器历史记录中
4. 请求可被收藏为书签
5. 数据类型为ASCLL码
GET
1 数据在请求体中,长度没限制
2. 不能被缓存
3. 请求参数不能保存在浏览历史中
4. 不能收藏为标签
5. 数据类型无限制
POST
13. GET和POST的区别
100(Continue):客户端应继续发送请求
101 协议切换
1xx表示请求已被接受,但需要后续处理
200(OK):请求已成功
201(Created):请求已成功,并且有个新的资源根据请求需要而创建
202(Accepted):服务器已接收请求,但是尚未处理,比如POST一个资源应当返回201,但由于性能原因未能立即创建,可以返回202
204(No Content):服务器成功处理了请求,但不需要返回任何实体内容,204响应禁止包含任何消息体。浏览器收到该响应后不应产生文档视图的变化
205(Reset Content):服务器成功处理了请求,但不需要返回任何实体内容,205响应禁止包含任何消息体。 与204不同的是,返回此状态码的响应要求请求者重置文档视图
2xx 表示请求已成功
301(Moved Permanently):被请求的资源已永久移动到新位置,永久性跳转,搜索引擎记录,权重迁移
302(Found):在一个网站或网页在短时间内临时移到其它位置的情况下使用,临时性跳转,容易网址劫持
304(Not Modified):一般用于静态文件的缓存
3xx 一般指重定向 Location
400(Bad Request):一般是参数不正确
401(Unauthorized):未授权 登录
403(Forbidden):服务器拒绝执行此请求 无权限
404(Not Found):一般是请求路径错误,导致资源找不到
405(Method Not Allowed):请求方法不一致
413(Request Entity Too Large):一般是请求数据大小超过服务器设置的大小
4xx 一般是客户端出错
500(Internal Server Error):后台服务错误
502(Bad Gateway):收到了无效响应,一般是服务器重启时出现
504(Gateway Time-out):加载超时
5xx 一般是服务器错误
14. HTTP状态码
方法 路径 http版本号
请求行
host: 主机域名
Connection: keep alive
cookie
Accept-Encodeing: gzip
Accrpt-Language:zh-cn
content-type: text/html、text/xml、text/plain、text/css、text/javascript、image/gif、image/jpeg、image/png、application/json、multipart/form-data
请求头
请求体
15. HTTP 报文
16.OSI七层模型
参数加密(参数存放签名),服务端接收后对除签名外的其他参数进行加密,然后对比,一致则合法
每次请求加上时间戳,接收后两次时间对比,超出某一个界限则认为请求无效
基于timestamp的方案
基于nonce的方案
17. 怎么防止篡改参数
参考:浏览器工作原理
浏览器 与 网络
多入口时entry是个对象
入口 entry
输出 output
webpack-dev-server
htmlwebpackplugin会在打包结束后,⾃动⽣成⼀个html⽂件,并把打包⽣成的js模块引⼊到该html中
filename
template
true 默认值,script标签位于html文件的 body 底部body script标签位于html文件的 body 底部head script标签位于html文件的 head中false 不插入生成的js文件,这个几乎不会用到的
inject
配置
html-webpack-plugin
将静态文件复制到构建目录
copy-webpack-plugin
css样式分离插件
mini-css-extract-pluginextract-text-webpack-plugin(webpack4已放弃此插件)
css压缩插件
optimize-css-assets-webpack-plugin
plugins
其他配置
消除不需要的引用。只能用于ES6模块
tree shaking
分析出模块之间的依赖关系,把那些被引用了一次的模块合并,减少代码体积
Scope Hoisting
webpack-dev-server 版本低 需升级
webpack4 中把 webpack-cli 抽离出来了,所以需要单独安装 webpack-cli3.x版本
html-webpack-plugin 不兼容 需升级
eslint-loader 版本低 升级
webpack4 需要使用vue-loader 15.0.0 至少。所以升级vue-loader
需安装vue-loader的plugin
删除 webpack.optimize 和 CommonsChunkPlugin 配置,原因是已经被启用
重新添加splitChunks配置,位置在 optimization 属性下
3 升 4 相关问题
extract-text-webpack-plugin CSS样式分离的插件
4 放弃的插件
webpack优化
你所知道的3xx状态码
如何理解HTTP响应的状态码?
HTTP 响应代码(MDN)
参考文献:
知识点
0 条评论
回复 删除
下一页