RSA和DSA的区别
他们都是非对称加密算法。
-
RSA: 他是基于大数分解(两个素数的乘积)实现的。它既可以作为签名(签名数字证书)使用也可以做加密(tls握手)使用。
-
DSA:他是基于整数有限域离散对数难题实现的。只能用于数字签名无法用于加密。
AES和DES区别
他们都是对称加密算法。
AES是DES的代替者,安全性高,性能很好,硬件也会多特殊的优化。
由于对称加密算法只能对特定长度明文加密,所以如果对于长明文,我们需要使用分组加密,然后将加密的秘钥段,连接起来。组成最终的秘钥。
内存泄露的原因
-
在函数中定义一个未声明的变量,会被放在window中,将一直保存到内存中,知道程序结束。
-
闭包的大量使用,因为闭包时,当外层函数执行上下文销毁后,内存函数应用的变量会被保存在堆中。
-
递归,没有设置终止条件。
-
js引用DOM节点。即使节点删除了,这引用也会保存到内存中。
通过JSON实现深拷贝的问题
-
对于对象的循环引用,会报错
-
不能处理函数,Symbol等类型。
flex的理解
这里说的flex是内容元素的css样式。由flex-grow, flex-shrink, flex-basis组成。默认值是0 1 auto;
这里值讨论flex-basis的使用。
-
设置元素主轴的初始大小。
-
当其他两个属性都生效时,那么flex-basis将会失效。
-
当width或者height 和 flex-basis同时存在,那么width或者height将会失效。
-
如果flex-basis:auto, 那么它将使用width或者height的值。如果width或者height也为auto或者未设置,那么它将由内容撑开。
flex: 1 = flex: 1 1 0%
flex: 2 = flex: 2 1 0%
flex: auto = flex: 1 1 auto
flex: none = flex: 0 0 auto,常用于固定尺寸不伸缩
如何阻止表单提交
-
将input:submit改为input:button。
-
监听form表单的submit事件,调用
event.preventDefault()
,或者返回false。
异步异常的捕获
我们知道try catch只能捕获存在于自己上下文的错误。但是异步异常就不能被catch。
但是有很多认为这两种方式也不能被捕获
-
回调函数中的异常
-
await后的promise抛出的异常。 以上两种方式是可以捕获的。
其实我们捕获异步异常,一般都是在异步函数中捕获,这样我们就可以直接使用try catch
,如果不在异步函数中,我们就直接将异步写在promise使用catch进行捕获。
那么如何捕获异步异常呢?
-
将异步写在promise中使用catch捕获。
-
但是如果promise中的异步抛出异常,catch可是不可以捕获的,需要使用reject传出异常信息。
这里还需要注意一下catch函数
-
catch只会捕获第一次抛出的异常。
-
~当catch和then方法都抛出异常,那么他只会捕获catch抛出的异常。 ~ 他是根据代码执行顺序进行捕获的。
new Promise((resolve, reject) => {
reject("====error")
}).catch(res => {
console.log("error1:", res)
throw new Error("======error catch")
}).then(res => {
throw new Error("=====error then")
}).catch(res => {
console.log("error2: ",res)
})
为什么0.1+0.2=0.30000000000000004
这个错误的根本原因是:大多数十进制无法正确的转换为二进制。 在计算机上计算时,是将十进制转换为二进制后进行计算,并将计算结果从二进制转换为十进制再次显示。
EcmaScrpt规范定义Number的类型遵循了IEEE754-2008中的64位浮点数规则定义的小数后的有效位数至多为52位导致计算出现精度丢失问题!
如何解决这个问题[1]
原生的解决方法
-
通过toFixed方法:使用定点表示法来格式化一个数值。
-
该方法接收digits参数。表示小数点后数字的个数。介于 0 到 20(包括)之间,实现环境可能支持更大范围。如果忽略该参数,则默认为 0。
-
然后返回格式化后的字符串。
let a = 0.1
let b = 0.2
const result = parseFloat((a + b).toFixed(1))
console.log(typeof result, result)
或者通过 *10 再 ÷10 的操作
let a = 0.1 + 0.2;
a = Math.round (a * 10);
a = a / 10;
console.log (a);
parseFloat()方法对于小数点后全为0的数字会保留整数。
parseFloat(1.000)
parseFloat(1.030)
伪类选择器
他们一般都是结合父标签使用的。
-
如果不结合父标签,那么他将会选择符合条件的所有。
-
如果不结合父标签,那么last-child将没有效果。(不知道为什么,是我测试的有问题吗)
<style>
p:last-child {
color: red;
}
</style>
<body>
<!-- <div> -->
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
<p>6</p>
<p>7</p>
<p>8</p>
<p>9</p>
<p>10</p>
<!-- </div> -->
</body>
如果给p标签加上div父标签,那么p: last-child将生效。
包含child的伪类受其他元素的影响
-
first-child: 表示选中第一个元素。一般都是组合元素。即前面需要加上父元素标签。 不然对于first-child可以选中很多。而且对于last-child标签而言。他只在嵌套元素下才能生效。
// 这个选择器就不起作用,因为p不是div中的第一个元素。
<style>
div p:first-child {
color: red
}
</style>
<div>
<span>0</span>
<p>1</p>
<p>2</p>
<p>3</p>
</div>
- nth-child(数字 / odd / even / 表达式):
-
数字从1开始的。
-
受其他元素影响。如果有其他元素,那么其他元素也参数索引。
-
even(2n)表示偶数元素选中,odd(2n + 1)表示奇数元素选中。
-
表达式:必须是包含n的表达式,并且n是从0开始计算的。
-
-
nth-last-child(): 表示从最后一个开始查找。
-
only-child。表示父元素中只能有一个标签,而且改标签为伪类选择器指定的标签。
不受其他元素的影响
-
first-of-type
-
last-of-type。这个并不需要有父元素包裹。
-
nth-of-type(数字 / odd / even / 表达式): 同上面一样
-
nth-last-of-type()
-
only-of-type: 表示父元素内,可以有多种标签,但是只能有唯一一个伪类选择器指定的标签,否则不起作用。 这类选择器,和上面的基本一样,唯一的区别就是他们只参考相同标签的元素。不会管其他类型的元素。
注意使用伪类选择器时,一定要加上父标签。
空标签伪类选择器
empty:标签内什么都没有才可以选中。包括空格。
axios的使用
-
通过axios.create(config)创建一个实例。并传入一些基本的配置,比如timeout, baseURL等等。
-
设置请求拦截器。这里一定要返回请求的配置。
instance.interceptors.request.use(config => {
return config;
},err => {
})
-
设置响应拦截器。如果后端接口比较规范的话,这里可以通过状态码整理响应数据。
instance.interceptors.response.use(res => {
return res.data;
},err => {
return err;
})
-
最后返回axios实例对象。
JWT 的原理
JWT生成的Token由三部分组成:
-
header
-
alg:采用的加密算法,默认是 HMAC SHA256(HS256),采用同一个密钥进行加密和解密;
-
typ:JWT,固定值,通常都写成JWT即可;会通过base64Url算法进行编码
-
-
payload
-
携带的数据,比如我们可以将用户的id和name放到payload中;
-
默认也会携带iat(issued at),令牌的签发时间;
-
我们也可以设置过期时间:exp(expiration time);
-
会通过base64Url算法进行编码
-
-
signature
-
设置一个secretKey,通过将前两个的结果合并后进行HMACSHA256(默认编码)的算法;
-
HMACSHA256(base64Url(header)+.+base64Url(payload), secretKey);
-
如果secretKey暴露是一件非常危险的事情,因为之后就可以模拟颁发token,也可以解密token;
-
注意:前两个字段是通过base64编码的,可以反向解码。但是最后一个字段一般不行。
http2的主动推送(server push)和websocket有什么区别
-
HTTP2 Server Push,一般用以服务器根据解析 index.html 同时推送 JPG/JS/CSS 等资源,而免了服务器发送多次请求
-
websocket,用以服务器与客户端手动编写代码去推送进行数据通信
http 502和504的区别
-
502 Bad Gateway。一般表现为你自己写的应用层服务(Java/Go/PHP)挂了,网关层无法接收到响应
-
504 Gateway Timeout。一般表现为应用层服务 (upstream) 超时,如查库操作耗时十分钟,超过了 Nginx 配置的超时时间
如何中断请求
web新推出的一个api: AbortConroller。具体请参考mdn[2] 他是一个类,通过创建对象获取signal信号量,他的作用是让controller对象和请求相关联,然后通过controller.abort()
来中断请求的发送。
const controller = new AbortController();
const signal = controller.signal;
abortBtn.addEventListener('click', function() {
controller.abort();
});
fetch(url, {signal}).then(function(response) {
})
并且axios的 v0.22.0 开始支持该api。具体请查看github[3]
const controller = new AbortController();
axios.get('/foo/bar', {
signal: controller.signal
}).then(function(response) {
});
controller.abort()