JS部分
如何取消http请求
XHR : .abort() 取消之后执行else
ajax : .abort() 取消之后执行error
axios: CancelToken.source()
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
})
TCP和UDP的区别
UDP是用户数据传输协议,无连接,首部开销小,速度快,但是容易丢包,可靠性低,可以实现一对多多对多;
TCP是传输控制协议,面向连接的,不会产生丢包等情况,首部开销大,相对UDP 传输速度较慢,可靠性高,全双工通信信道。只能点到点。
TCP三次握手 四次挥手
- TCP报文头部
16位源端口号,16位目标端口号
32位序号:seq
32位确认序号:ack
- TCP的标志位
SYN(synchronous):建立联机
ACK(acknowledgement):确认
FIN(finish):结束
三次握手:
客户端发起一个连接请求,带着标识符SYN=1,seq=J;
服务端接收到这个请求,并响应,返回了一个ACK =1,SYN=1的应答,ack=J+1,seq=K;
客户端收到这个ACK,和SYN后,发送ACK=接收到的SYN的值,ack=K+1返回给服务端,确认信息成功,就可以开始互相发送数据了;
我:(发送消息)小明能收到消息吗,收到回复111
小明:(收到消息了)收到,111,你能收到吗,收到回复666
我:(收到并回复)收到收到666
流程图:
C-S:发送SYN=1,seq=J
C端关闭━主动打开,S端关闭━被动打开
S-C:发送ACK=1,SYN=1,ack=J+1,seq=K
S端处于监听状态,C端处于同步已发送状态
C-S:发送ACK=1,ack=K+1
C端建立连接,S端建立连接
四次挥手:
客户端发起一个终止请求FIN=1,seq=x;
服务端响应(我知道你想干嘛了,等我一下)ACK=1,ack=x+1;
服务端响应(我好了,关吧关吧)FIN=1,seq=y;
客户端响应ACK=1,seq=y+1;
我:妈我要出门啦
妈:哦,等一下
妈:给你两百块,去玩吧
我:好的,拜拜
流程图:
C-S:FIN=1,seq=x
C建立连接状态━终止等待1,S端建立连接到━关闭等待
S-C:ACK=1,ack=x+1
S关闭等待持续,C终止等待1━终止等待2
S-C:FIN=1,seq=y
C端终止等待━时间等待,S最后确认
C-S:ACK=1,seq=y+1
C端时间等待持续一会后关闭,S端关闭
缓存
强缓存
协商缓存
304 200
ETag:hash md5 更新
请求头cache-control
响应式布局 自适应布局
- @media screen :媒体查询
- rem 根据根节点的font-size来调节;em通过父元素字体大小来调节;
// 确定根节点字体大小,结合rem实现响应式 (function(a, d) { var b = a.documentElement, e = "orientationchange" in window ? "orientationchange" : "resize", c = function() { var a = b.clientWidth; a && (b.style.fontSize = Math.min(a, 750) / 375 * 100 + "px") }; a.addEventListener && (d.addEventListener(e, c, !1), a.addEventListener("DOMContentLoaded", c, !1)) })(document, window);
- vw 通过视口的宽高来确定
- % 根据父元素的宽高的百分比
- flex 兼容IE10+
- grid 兼容IE10+
闭包
闭包,mdn给的释义是函数与其周围此法环境的捆绑,可以访问自由变量;你不知道的JavaScript中定义的是能够记住并访问到当前作用域,那么就产生了闭包。闭包的作用有二:一是保存变量,二是保护外部变量不受污染,像柯里化函数,回调函数,模块化等都是闭包的实际应用
cookie、session、local storage, session storage
cookie : 同源请求都能拿到,存取没有其他两个方便 需要用document.cookie去获取在进行匹配,cookie可以设置过期时间
getCookie: function (name) {
var arr;
var reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
if (arr = document.cookie.match(reg)) {
return unescape(arr[2]);
} else {
return null;
}
},
setCookie:function (name, value, day) {
if (day !== 0) { //当设置的时间等于0时,不设置expires属性,cookie在浏览器关闭后删除
var expires = day * 24 * 60 * 60 * 1000;
var date = new Date(+new Date() + expires);
document.cookie = name + "=" + escape(value) + ((day == null) ? "" : ";expires=" + date.toGMTString()) + ';path=/;';
} else {
document.cookie = name + "=" + escape(value);
}
},
sessionstorage过期时间 : 关闭浏览器页面即过期;
localstorage 存储于本地域名下,永久有效,当然也可以自己加一个过期时间 存取时比较
getItem(name)
setItem(name,value)
跨域是怎么产生的,如何解决
非同源的网址,需要从 不同协议 不同域名 不同端口 的网址下去请求资源,就会产生跨域的问题。
解决办法:
- Nginx反向代理 :客户端找代理服务器请求资源,代理服务器反向拿到数据给客户端
- 添加响应头:
access-control-allow-origin
- jsonp:
通常为了减轻web服务器的负载,我们把js、css、图片等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许。html中有的标签天然支持跨域,比如<script src="http://www.baidu.com"></script>
但是只支持get请求。
XSS、CSFR、防暴刷
XSS跨站脚本攻击 :
是指攻击者在网站上注入恶意客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式
分类: 存储型 反射型
防御:转义 请求头添加x-xss-protection
CSFR跨站请求伪造:在url后加入一些恶意的参数,从而达到攻击者的目的。
防御:禁止第三方请求携带本站cookie 请求加token验证 请求头添加X-Frame-Options
原型原型链
JS原型就是prototype,函数中除了箭头函数都有这个原型属性,对象的原型可以通过__proto__来访问,在函数执行中,若要访问某个变量的成员,那么就会通过原型链来查找,所谓原型链就是以当前对象为起点开始,找到当前对象的原型,原型的原型…直到最终找到基类Objetc.__proto__也就是null停止,当你想扩展原型方法时的时候可以直接加到prototype,不可枚举的,instancof也是基于原型来判断实例是否属于某一个类的。
JS同步异步 事件循环
JS是单线程的脚本语言,也就是说浏览器新开一个页面时,就相当于新开了一个进程,这里只会分一个线程给JS引擎渲染,还会分其他线程用于GPU渲染,HTTP请求等,所以说JS加载顺序就是自上而下进行的,js中的异步是通过EventLoop来实现的,js中的大部分代码都是同步代码,但是像定时器,http请求,promise.then等,都是异步代码,在执行中会先等待同步任务执行完,在进行异步微任务的执行,执行完异步微任务就继续异步宏任务,进行一个事件循环
git
权限
你都做过哪些Vue的性能优化?
编码阶段:
尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
如果需要使用v-for给每项元素绑定事件时使用事件代理
SPA 页面采用keep-alive缓存组件
在更多的情况下,使用v-if替代v-show
key保证唯一
使用路由懒加载、异步组件
防抖、节流
第三方模块按需导入
长列表滚动到可视区域动态加载
图片懒加载
SEO优化
预渲染
服务端渲染SSR
打包优化:
压缩代码
Tree Shaking/Scope Hoisting
使用cdn加载第三方模块
多线程打包happypack
splitChunks抽离公共文件
sourceMap优化
用户体验
骨架屏
PWA
还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启gzip压缩等。
(优化是个大工程,会涉及很多方面,这里申请另开一个专栏)
前端如何进行seo优化
合理的title、description、keywords:搜索对着三项的权重逐个减小,title值强调重点即可;description把页面内容高度概括,不可过分堆砌关键词;keywords列举出重要关键词。
语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页
重要内容HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,保证重要内容一定会被抓取
重要内容不要用js输出:爬虫不会执行js获取内容
少用iframe:搜索引擎不会抓取iframe中的内容
非装饰性图片必须加alt
提高网站速度:网站速度是搜索引擎排序的一个重要指标
1000-div问题
一次性插入1000个div,如何优化插入的性能
使用Fragment
var fragment = document.createDocumentFragment();
fragment.appendChild(elem);
向1000个并排的div元素中,插入一个平级的div元素,如何优化插入的性能
先display:none 然后插入 再display:block
赋予key,然后使用virtual-dom,先render,然后diff,最后patch
脱离文档流,用GPU去渲染,开启硬件加速