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抛出的异常。 以上两种方式是可以捕获的。
那么如何捕获异步异常呢?
- 将异步写在promise中使用catch捕获。
- 但是如果promise中的异步抛出异常,catch可是不可以捕获的,需要使用reject传出异常信息。
这里还需要注意一下catch函数
- catch只会捕获第一次抛出的异常。
- 当catch和then方法都抛出异常,那么他只会捕获catch抛出的异常。
new Promise((resolve, reject) => { reject("====error") }).catch(res => { console.log("error1:", res) // ====error throw new Error("======error catch") }).then(res => { throw new Error("=====error then") }).catch(res => { console.log("error2: ",res) // Error: ======error catch })
为什么0.1+0.2=0.30000000000000004
这个错误的根本原因是:大多数十进制无法正确的转换为二进制。在计算机上计算时,是将十进制转换为二进制后进行计算,并将计算结果从二进制转换为十进制再次显示。
EcmaScrpt规范定义Number的类型遵循了IEEE754-2008中的64位浮点数规则定义的小数后的有效位数至多为52位导致计算出现精度丢失问题!
原生的解决方法
- 通过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) // number 0.3
或者通过 *10 再 ÷10 的操作
let a = 0.1 + 0.2; // 0.30000000000000004 a = Math.round (a * 10); // 乘以 10 → 舍入 "3.0000000000000004" → "3" a = a / 10; // 3 / 10 console.log (a); // 0.3
parseFloat()方法对于小数点后全为0的数字会保留整数。
parseFloat(1.000) // 1 parseFloat(1.030) // 1.03
伪类选择器
他们一般都是结合父标签使用的。
- 如果不结合父标签,那么他将会选择符合条件的所有。
- 如果不结合父标签,那么last-child将没有效果。(不知道为什么,是我测试的有问题吗)
<style> /* 这个必须具有嵌套的元素。 但是last-child就不会有这个限制 */ 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等等。
- 设置请求拦截器。这里一定要返回请求的配置。
// 1. 请求拦截 instance.interceptors.request.use(config => { // console.log(config); // 当请求可以发出时 我们拦截 对其做一些修饰 // 1. config中的一些信息不符合服务器需求 // 2 每次发送请求时,都希望有一个loading // 3. 某些网络请求都必须携带一些特定信息(token) return config;//拦截修改后 ,一定要将config返回 让服务器得到请求 来做出响应 },err => { // console.log(err); })
- 设置响应拦截器。如果后端接口比较规范的话,这里可以通过状态码整理响应数据。
// 2. 响应拦截 instance.interceptors.response.use(res => { // console.log(res);//此时是服务器返回的数据 return res.data;//返回数据本身 },err => { // console.log(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他是一个类,通过创建对象获取signal信号量,他的作用是让controller对象和请求相关联,然后通过
controller.abort()
来中断请求的发送。
const controller = new AbortController(); const signal = controller.signal; abortBtn.addEventListener('click', function() { // 取消发送 controller.abort(); }); // 在配置中传入signal fetch(url, {signal}).then(function(response) { })
并且axios的 v0.22.0 开始支持该api。具体请查看github
const controller = new AbortController(); axios.get('/foo/bar', { signal: controller.signal }).then(function(response) { //... }); // cancel the request controller.abort()