春招之路-前端

前端

1.跨域

同源策略:域名,端口,协议
jsonp:html中script的src属性获取其他源数据,不受同源策略影响,参数放在?后面,通过其他script获取返回数据,只能处理GET,易受XSS攻击
cors:允许浏览器跨源发送XMLHttpRequest请求,与ajax代码没有区别,发现跨域请求,对请求头做处理
简单请求:请求头中加入origin,检查响应头中是否有Access-Control-Allow-Orign字段
预检请求:先发送OPTION请求检查能否跨域,返回支持方法和字段,再发起简单请求
区别:GET,HEAD,POST/Accept,Accept-Language,Content-Language,Content-Type
Nginx反向代理:服务器之间没有跨域限制,浏览器先发送请求给Nginx配置的代理服务器,再转发给真正的服务器
iframe跨域:子域名不同,window.name window.postMessage
还有websocket和nodejs中间件(代理服务器)

2.安全 XSS CSRF

XSS攻击 跨站脚本攻击
存储型XSS 将脚本注入到数据库中,持久
反射型XSS 脚本在URL中,获取document.Cookie
DOM型XSS 通过脚本修改页面内容,不向服务端发请求
防范:对/,<,>," 字符进行转义,escapeHTML(),设置白名单过滤不允许的字段
CSRF 跨站请求伪造
盗用用户身份,以用户名义发送请求,跳转到第三方网站,利用cookie,image src GET,隐藏表单 POST
防范:请求头中添加referer验证是否跨域,隐藏token校验
每次请求生成CSRF token放在session中,服务器进行验证
双重验证(验证码或密码)

3.模块化

将一个复杂系统分解为多个模块以方便编码
发展:
最早使用script标签引入js文件,没有私有空间,模块直接在全局工作,污染全局作用域,命名冲突,无法管理依赖关系
window.module命名空间方式,每个模块只暴露一个全局对象,其他成员挂载到全局对象,只解决命名冲突
匿名函数,立即执行,解决了私有空间问题,给匿名函数传参作为依赖声明
但是模块的加载不受代码控制,于是出现模块化规范:
AMD采用异步方式加载依赖的模块,不用转换代码直接运行在浏览器环境,依赖前置,提前声明依赖,require.js
CMD异步加载,依赖就近,用到再require,延迟执行,sea.js
CommonJS通过require方法同步加载依赖,通过module.exports导出需要暴露的接口,
优点:可以在Nodejs环境,缺点:不能直接运行在浏览器环境,必须转成es5,不能并行加载
esm:import导入export导出对外接口,浏览器和node都支持,无法直接运行在大部分js环境,需要转为es5
区别:Commonjs属性在脚本运行时确定,输出的是值,esm编译时动态加载,输出值的引用,import只读const不能赋值,import/export提升到顶级

4.webpack 模块化打包工具

打包过程:
读取配置文件,创建compiler对象,调用apply方法挂载plugin监听
从entry里配置的module开始递归解析entry依赖的所有module
每找到一个module,根据配置的loader找出转换规则,并在合适时机触发plugin逻辑
对module进行转换,再解析当前module依赖的module
根据entry分组,一个entry和所有依赖的module分为一个chunk,仍可通过plugin修改
根据output配置将所有chunk转换成文件输出
Loader:webpack只识别js和json模块,loader可以将不同格式文件转换,
将代码进行分析,构建AST,遍历进行定向修改,重新生成新的代码字符串
babel-loader:将es6转换成es5,
原理:parser将代码转换为AST,transformer用配置好的plugin把es6的AST转成es5的AST,generator生成新代码
css-loader:解析css文件,style-loader:css解析后内容挂载到页面,
file-loader:打包文件,url-loader打包图片
Plugin:编译周期中,webpack触发事件钩子,plugin监听事件,对打包内容进行定向修改
html-webpack-plugin:压缩html,clean-webpack-plugin:清理目录文件
解决了什么问题:
可以将es6编译为es5,解决环境兼容问题
模块文件过多,每一个文件需要单独从服务器请求回来,频繁发送网络请求影响效率,
把所有依赖打包成一个bundle.js文件,通过代码分割成单元片段并按需加载,动态导入
把html,css等不同种类的资源模块化,将各个模块通过loader模块转换器和plugins扩展插件处理,然后打包在一起

5.vite

要求项目完全由esm模块组成,不能用commonjs不能直接在nodejs中使用
webpack缺点:webpack先打包,启动开发服务器,给予打包结果,
将所有模块打包到一个bundle.js文件中,修改需要重新打包,构建速度慢
vite直接启动开发服务器,请求哪个模块再实时编译,不需要打包,分析依赖快,支持热更新
客户端与服务端建立websocket连接,代码被修改,服务端通知客户端请求修改模块代码
原理:
vite启动一个koa服务器拦截浏览器请求esm的请求,通过path找到对应的文件以esm格式返回客户端,
使用esmodule lexer处理,返回文件中导入的模块并以数组形式返回,通过数组判断是node_module模块进行重写
vue文件拆解为script,template,css发送请求,静态资源处理成esmodule

6.异步defer,nexttick,async,Promise

defer延迟调用在return之前调用,多个defer反序调用
async/await是generator/yield语法糖,将函数变成generator函数,使用自动执行函数执行,await=yield
遇到await返回Promise对象,后面的内容放到Promise.then中,被拒绝使用try/catch或函数后加.catch
Promise本身是同步的立即执行函数,有三种状态,当执行resolve或者reject的时候,改变状态,然后先执行.then,出现异常.catch
process.nextTick,属于微任务,当前执行栈的尾部,eventloop之前触发,会阻塞IO
async/await优点?
async会让代码简洁,看起来像同步代码,不需要处理resolve的值,通过try/catch处理异常,不会造成then链式调用
script标签中defer和async区别?
defer脚本加载完不会立刻执行,等文档解析完成后执行,不会影响页面构造,DOMContentloaded触发前执行
async脚本加载完停止解析html,立刻执行脚本,乱序

7.语义化

增强可读性,便于开发和维护
有利于SEO,搜索引擎的爬虫依赖于标签来确定上下文和各个关键字的权重,让搜索引擎爬虫获取到更多有效信息,提升搜索量
方便其他设备的解析,有利于无障碍阅读
header,footer,aside不相关内容,address,em重音,strong粗体,abbr缩写,time时间
h5新增:article,section,nav,aside,header,footer,time

8.发布订阅模式和观察者模式

观察者模式包含观察者和被观察者,观察者知道被观察者,同步,松耦合关系
发布订阅模式包含发布者订阅者和消息代理,发布者和订阅者不知道对方存在,消息存放在消息队列,通过代理发布,异步,不存在耦合

9.node中间件

nodejs中,中间件主要指封装http请求细节处理的方法,本质是回调函数,参数包含ctx(请求对象+响应对象)和next执行下一个中间件的函数
通过next函数联系,执行next()后会将控制权交给下一个中间件,如果没有中间件没有执行next后将会沿路折返,将控制权交换给前一个中间件
功能:token校验,日志模块

10.浏览器缓存

强缓存
Expires(http1.0)资源过期时间,客户端和服务端可能不一致
Cache-Control资源的有效期,max-age:xx秒后失效(优先级高于Expires)
协商缓存
Last-Modified资源的最后修改时间,
if-Modified-Since比较请求资源的最后修改时间,改动返回200,没有改动返回304,缺点:周期性修改不改变内容,会请求新数据
Etag响应头中返回资源内容的唯一标识,
if-None-Match比较请求头的if-None-Match与Etag,不一致命中(优先级高于上面的),if-Match与之相反
流程:
先检测强缓存类型是否有效,如果命中,直接从本地获取资源
没命中,向服务器发送请求,通过请求头验证协商缓存,称为http验证,命中返回请求不返回资源
告诉客户端从缓存中获取,没命中返回资源

11.单页应用与多页应用的区别
单页面应用(SPA)多页面应用(MPA)
组成一个主页面和多个页面片段多个主页面
刷新方式局部刷新整页刷新
url模式哈希模式历史模式
SEO搜索引擎优化难实现,可使用SSR方式改善容易实现
数据传递容易通过url、cookie、localStorage等传递
页面切换速度快,用户体验良好切换加载资源,速度慢,用户体验差
维护成本相对容易相对复杂
12.内存泄露 使用调式工具memory

未声明的全局变量
dom存在数据结构中,删除dom节点依然在内存中
setinterval中的资源
闭包中循环引用

13.Express和Koa

express,koa框架都是基于nodejs,
koa中间件采用洋葱圈模型,U型执行,每一次next()后,都会进入下一个中间件,
等最后一个中间件执行完以后,再从最后一个中间件的next()之后的代码往回执行,使用async/await同步方法写异步
express中间件按照顺序线性执行,内置很多中间件,包含路由、视图渲染特性,利用回调函数

14.ajax

异步html和xml,传统的HTML表单方式进行页面的更新时,每次都要将请求提交到服务器,ajax不需要重新加载网页的情况下更新数据
过程
1.创建XMLHttpRequest对象
2.规定请求的类型,URL以及是否异步处理请求,ajax.open(‘GET’,url,true)
3.发送信息至服务器时内容编码类型,ajax.setRequestHeader(“Content-type”,“application/x-www-form-urlencoded”)
4.发送请求,ajax.send(null)
5.接受服务器响应数据,ajax.onreadystatechange=function(){}

15.浏览器本地存储

localstorage,sessionstorage
IndexDB 浏览器本地数据库
键值对存储,主键唯一,异步操作不会造成浏览器死锁,同源限制,支持事务回滚,存储空间大,支持二进制存储
打开数据库:window.indexedDB.open,新建数据库,新建索引,增删改查

Vue

1.介绍一下什么是vue

Vue是一个渐进式框架(不做职责以外的事,主张最少),轻巧,高性能,可组件化的MVVM库,自下向上增量开发,
实现响应式的数据绑定,组件化的开发和虚拟dom
MVVM通过数据驱动视图显示,Model和View之间通过ViewModel同步,避免直接操作dom树
MVC节点操作,Model和View耦合度高,大量dom操作页面渲染性能降低

2.Vue响应式原理

Vue实例被创建时,vue遍历data中的属性,用Object.defineProperty给每个属性添加getter和setter
mount阶段创建watcher类的对象,一个watcher对应一个component
watcher调用组件的render函数生成虚拟dom,使用属性值时触发getter函数,将watcher写入sub数组
当data属性发生改变之后触发setter函数,遍历sub里所有的watcher对象,通知它们去重新渲染组件

2.router和route

router是路由对象,里边包含了很多属性和子对象,主要是用来进行路由跳转的
提供三种路由模式
hash模式:默认模式,通过路径中的hash值来控制路由跳转,不会重新加载页面,不存在兼容问题,
在正常路径后跟一个#号,匹配#后边的路径为前端路由,通过window.onhashchange方法来操控,
路由改变的时候切换内容,不会包含在http请求中,对后端无影响
history模式:不使用#,使用/,配置window.location.mode:history,
利用H5中新增的pushState和replaceState方法,基于浏览器历史记录访问指定页面,改变url地址,不会发送请求,
但是需要后台配置支持,刷新页面,向服务器发送请求,如果后台没有响应资源报404
abstract模式:所有js环境,如服务端和Node.js环境,不依赖于浏览器环境的一种模式
VueRouter默认使用hash模式,如果检测到没有浏览器API的时候,就会使用abstract模式
跳转方法:< router-link>< router-view>
this. r o u t e r . p u s h ( ) h i s t o r y 栈中添加一个记录 t h i s . router.push()history栈中添加一个记录 this. router.push()history栈中添加一个记录this.router.replace()history栈中不会有记录,点击返回会跳转到上上个页面,直接替换了当前页面
this.$router.go(n)向前或者向后跳转n个页面
route表示当前的路由信息,用来获取路径内容

3.Vue2和Vue3区别

Vue2使用Object.defineProperty的setter和getter进行双向绑定,不能监听所有属性和新增属性,只能遍历
选项式API:data,computed,watch,methods
生命周期钩子函数beforexxx,xxxed:create,mount,update,destroy
Vue3使用es6新增proxy代理,支持TS
Tree-shaking Support摇树优化,支持按需导入,依赖esmodule编译阶段静态分析,
找到没有引入的模块并标记,不会打包进去
组合式API:选项式API随着业务复杂度提高维护复杂,复用性低,抽离引用mixin混入造成命名冲突和来源不明
组合式API通过引入组件避免了命名冲突的问题,可以调用局部变量
所有的方法,属性生命周期函数码放在setup中,取消了this,组件生命周期只执行一次,先执行setup方法
生命周期钩子函数onBeforexxx,onxxxed:mount,update,unmount(create不需要显性调用)

4.虚拟DOM:先比较再更新节点,解决浏览器性能问题

Vue2.x加入,本质是js对象,有跨平台特性
模板通过渲染函数->虚拟DOM->真实DOM,与旧节点做对比,实现部分更新

5.为什么使用key?index不行吗?

Diff算法是交叉对比的过程,使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,高效的更新虚拟DOM
如果用index作为key,与不加key一样,只适于不依赖子组件状态或临时DOM状态

6.Vue diff

同层树节点比较算法,用来比较Vue渲染前后的新旧节点,深度优先,从两边向中间循环
相同节点复用,没有找到就新建节点

7.组件通信

父=>子 子<:msg=“”> 子 porps=[“msg”]接收 {{msg}}
子=>父 子this.$emit(“_”, _ ) 父<@__:“getSon”>接收 getSon(val){}
this.$childeren获取子组件数组this.$parent获取父对象
provide/inject,ref/refs,storage,$sttrs/$listeners
兄弟eventBus:this.$EventBus.$on(’ _ ‘, () =>{} this.$EventBus.$emit(’ _ ‘, num)this.$EventBus.$off(’ _ ')注销
Vuex:this.$store

8.父子组件生命周期

顺序:父beforecreate,created,beforemount,子组件生命周期,父mounted
update/destroy:父beforeupdate,子beforeupdate,updated,父updated

9.axios特点

基于promise的http库,可以拦截请求和响应,转换请求数据和响应数据,将内容自动转换成JSON,
安全性好,支持防御CSRF
常用方法:get,delete,post,put

10.动态路由,路由守卫

第一种:设置权限路由列表,包含路由路径,meta元数据控制按钮权限和路由角色信息,再设置一个公共路由,创建路由守卫,
获取登录的token,判断是否登录,从vuex中获取用户角色,将角色信息存到sessionstorage,再存到vuex中,获取路由表通过addrouter注入到公共路由,未登录跳转登录页
第二种:前端只有公共路由,每次登录通过后端返回路由,先存到sesionstorage再存到vuex中,将component转换成组件对象,遍历子路由,创建路由守卫,
获取登录的token,判断是否登录,判断vuex或sessionstorage是否有路由,没有异步请求路由,addrouter注入公共路由
路由守卫,防止跳过登录界面,是路由跳转过程中的一些钩子函数,路由跳转时请求角色的权限,防止其他人拿到路由登录页面,返回404
每次刷新查询sessionstorage是否有路由,然后同步到vuex中

11.Vuex

vuex储存在内存中
结构:state,getter,mutation,action,module
state:保存组件的状态
getter:有时候state中的值取出之后,需要进行过滤,想要复用这个处理函数,需要将函数写入getter中
mutation:mutation类似于事件,每个mutation包含事件类型和回调函数,调用时使用store.commit方法触发mutation函数,
devtool对比前后状态,所以mutation必须是同步函数,否则不知道回调函数什么时候被调用
action:提交mutation,可以包含异步操作,通过store.dispatch分发,可以处理返回的promise,再返回一个promise
工作流程?
调用this.$store时,在组件中通过dispatch触发actions提交修改数据的操作,通过commit来触发mutations修改数据,
mutations接收到commit的请求,就会通过mutate来修改state里面的数据,由store触发每一个调用它的组件的更新
为什么需要mutation更改数据?
Vuex是单向数据流,需要知道数据修改的来源,mutation一般传入的是对象,可以定位修改的来源

12.路由懒加载

项目build打包后,一般情况下会放在bundle.js文件中,但是如果很多的页面都放在同一个js文件中,会造成页面非常大
如果一次性的从服务器中请求下来这个页面,可能会花费一定时间,用户体验不好
懒加载主要作用是将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才加载对应的组件,否则不加载
实现懒加载
ES6的import(),webpack的require,ensure()
vue-router配置路由,使用vue的异步组件技术,配置路由时候使用component:resolve=>require([‘路由地址’], resolve)

小程序

双线程

基于微信,限制允许声明的组件,在线更新,不依赖于微信,不能操作微信的功能,保证线程安全性,使用类似于webworker的线程
不允许js直接操作组件,需要setData异步更新,使用类似于Vue的diff算法更新,由native作为中间媒介转发给渲染线程
渲染层交互触发event,event传递给逻辑层,逻辑层经过处理通过setdata传递给渲染层,渲染层data渲染为UI

冷启动,热启动

冷启动:用户首次打开,或者销毁后再次打开,小程序需要重新加载,调用onload->onshow
热启动:用户已经打开过,在一定时间内再次打开,小程序未被销毁,调用onshow

生命周期

App
onlaunch初始化时触发,只能触发一次
onshow初始化完成从后台切换到前台显示时触发
onhide切换到后台时触发
onError发生错误时触发
页面
onload首次进入加载时触发
onshow加载完成后,后台切换到前台或重新进入时触发
onready首次渲染完成时触发
onhide前台切到后台触发
onUnload页面卸载时触发
顺序:App中的onlauch,onshow,页面的onload,onshow,onready

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值