1. Nginx使用proxy_pass反向代理时,session丢失的问题
如果只是host,端口转换,则session不会丢失。例如:
location /testwx {
proxy_pass http://127.0.0.1:8080/testwx;
}
如果路径也变化了,则需要设置cookie的路径转换,nginx.conf的配置如下
location /testwx {
proxy_pass http://127.0.0.1:8080/wx;
proxy_cookie_path /wx /testwx;
}
2. rpc之gRPC
gRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。
基于HTTP/2,提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。
可以节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。
gRPC 的协议设计上使用了HTTP2 现有的语义,请求和响应的数据使用HTTP Body 发送,其他的控制信息则用Header 表示。
IDL使用ProtoBuf,gRPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议(类似于XML、JSON、hessian)。
HTTP/2 传输的数据是二进制的。相比 HTTP/1.1 的纯文本数据,二进制数据一个显而易见的好处是:更小的传输体积。这就意味着更低的负载。
3. 其他rpc
thrift,dubbo,motan等,底层协议归纳为有:motan协议,tcp长连接,Dubbo 协议、 Rmi 协议、 Hessian 协议、
HTTP 协议、WebService 协议、Dubbo Thrift 协议、Memcached 协议,tpc/http/frame,http2,另外在分布式服务治理、消息序列化、负载均衡、
容错、注册中心等方面,各个RPC框架配合相应的组件服务,各有特点。
4. 手写jsonp
function jsonp(url, data = {}, callback = 'callback') {
data.callback = callback
let params = []
for (let key in data) {
params.push(key + '=' + data[key])
}
let script = document.createElement('script')
script.src = url + '?' + params.join('&')
document.body.appendChild(script)
return new Promise((resolve, reject) => {
window[callback] = (data) => {
try {
resolve(data)
} catch (e) {
reject(e)
} finally {
script.parentNode.removeChild(script)
console.log(script)
}
}
})
}
5. Vue虚拟DOM(VDOM)和diff算法
虚拟DOM是利用 了js的对象的Object的对象模型来模拟真实DOM, 那么它的结构是一个树形结构。
diff算法是同级比较的,diff算法的比较,四种情况:
1)此节点是否被移除 -> 添加新的节点
2)属性是否被改变 -> 旧属性改为新属性
3)文本内容被改变-> 旧内容改为新内容
4)节点要被整个替换 -> 结构完全不相同 移除整个替换
6. 关于vue的props
父子组件传值时,父组件传递的参数,数组和对象,子组件接受之后可以直接进行修改,并且会传递给父组件相应的值也会修改。
如果传递的值是字符串,直接修改会报错。不推荐子组件直接修改父组件中的参数,避免这个参数多个子组件引用,无法找到造成数据不正常的原因。
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。额外的,每次父级组件发生更新时,
子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
7. MVVM 之 Vue.js
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,
这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,
专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的,
因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
Vue.js 是采用 Object.defineProperty 的 getter 和 setter,并结合观察者模式来实现数据绑定的。
当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
8. Web安全之CSRF攻击
CSRF攻击是源于Web的隐式身份验证机制!Web的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。
CSRF攻击的一般是由服务端解决:
1)尽量使用POST,限制GET
2)浏览器Cookie策略(拦截第三方本地Cookie的发送),第三方cookie的使用场景通常是iframe,例如www.a.com潜入了一个www.ad.com的广告iframe,
那么www.ad.com设置的cookie不属于www.a.com,被称作第三方cookie。
3)加验证码(出于用户体验考虑,网站不能给所有的操作都加上验证码)
4)Referer Check(服务器并不是什么时候都能取到Referer)
5)Anti CSRF Token,现在业界对CSRF的防御,一致的做法是使用一个Token(Anti CSRF Token):
a. 用户访问某个表单页面。
b. 服务端生成一个Token,放在用户的Session中,或者浏览器的Cookie中。
c. 在页面表单附带上Token参数。(此处是重点,token在表单中提交参与验证,而不是cookies中)
d. 用户提交请求后, 服务端验证表单中的Token是否与用户Session(或Cookies)中的Token一致,一致为合法请求,不是则非法请求。
这个Token的值必须是随机的,不可预测的。由于Token的存在,攻击者无法再构造一个带有合法Token的请求实施CSRF攻击。
另外使用Token时应注意Token的保密性,尽量把敏感操作由GET改为POST,以form或AJAX形式提交,避免Token泄露。
注意:
CSRF的Token仅仅用于对抗CSRF攻击。当网站同时存在XSS漏洞时候,那这个方案也是空谈。所以XSS带来的问题,应该使用XSS的防御方案予以解决。
9. 同源策略
由NetScape提出的一个著名的安全策略。所谓的同源,指的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,
不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。
补一点:为什么form表单提交没有跨域问题,但ajax提交有跨域问题?
因为原页面用 form 提交到另一个域名之后,原页面的脚本无法获取新页面中的内容。所以浏览器认为这是安全的。
而 AJAX 是可以读取响应内容的,因此浏览器不能允许你这样做。如果你细心的话你会发现,其实请求已经发送出去了,你只是拿不到响应而已。
所以浏览器这个策略的本质是,一个域名的 JS ,在未经允许的情况下,不得读取另一个域名的内容。但浏览器并不阻止你向另一个域名发送请求。
10. vue中的slot与slot-scope
插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示、以及怎样显示由父组件来决定,父组件把的slot部分用UI内容填充。其中,作用域插槽(slot-scope)要求在slot上面绑定数据,这个数据来自子组件,但是传到父组件,交给父组件渲染。
11. 消息队列
消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。
RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq。甚至现在部分NoSQL也可做消息队列,如 Redis。
使用场景:异步处理、应用解耦、流量削峰。
RabbitMQ默认15672端口,登陆管理界面,打开浏览器输入:http://localhost:15672
使用消息队列需要考虑下面几个问题:
如何保证消息的幂等性(消息重复),对于消息中间件的幂等性问题,一般通用的处理方案是给消息一个唯一的ID,每次做业务处理之前判断是否消费过。如果消费过,那么直接抛弃该消息,否则进行业务处理。
如何保证消息的顺序性(消息有序),一般通用的处理方案是保证局部的消息有序。对于订单消息、支付消息的例子,我们一般会将订单消息和支付消息里的用户ID作为key,将其分配到同一个 partition 中,这样它们就是有序的。
如何保证消息的可靠性(消息丢失),对于 Kafka 来说,可能发生消息丢失的几个节点分别是:生产者丢失消息、broker丢失消息、消费者丢失消息。
那么如何解决数据丢失的问题呢?目前来说有两种方式,一种是在消息中间件层面解决,另一方面是在业务层面通过消息补偿解决。
消息中间件层面。选择不会丢失的消息中间件,例如 RocketMQ 对于消息的确认机制比较严格,可以保证消息不丢失,而 Kafka 则无法保证消息不丢失。
业务层面(消息补偿)。意思是允许中间件出现消息丢失,但是通过业务层面来做消息补偿。不同的业务场景,消息补偿的形式不一样,需要具体情况具体分析。
那么,为什么RocketMQ可以保证消息不丢失?
1)从Producer分析:如何确保消息正确的发送到了Broker?
状态超时或者失败,则会触发默认的2次重试。如果消息发送Ack失败的话,此消息会存储在CommitLog当中,但是对ConsumerQueue是不可见的。
可以在日志中查看到这条异常的消息,严格意义上来讲,也并没有完全丢失。
2)从Broker分析:如果确保接收到的消息不会丢失?
消息支持持久化到Commitlog里面,即使宕机后重启,未消费的消息也是可以加载出来的,
Broker自身支持同步刷盘、异步刷盘的策略,可以保证接收到的消息一定存储在本地的内存中,
Broker集群支持 1主N从的策略,支持同步复制和异步复制的方式,同步复制可以保证即使Master 磁盘崩溃,消息仍然不会丢失。
3)从Consumer分析:如何确保拉取到的消息被成功消费?
消费者可以根据自身的策略批量Pull消息
Consumer自身维护一个持久化的offset,标记已经成功消费或者已经成功发回到broker的消息下标,
如果Consumer消费失败,那么它会把这个消息发回给Broker,发回成功后,再更新自己的offset,
如果Consumer消费失败,发回给broker时,broker挂掉了,那么Consumer会定时重试这个操作,
如果Consumer和broker一起挂了,消息也不会丢失,因为consumer 里面的offset是定时持久化的,重启之后,继续拉取offset之前的消息到本地。
12. Git分支误删了怎么办?
git本地分支误删,同时把远程分支也误删了,怎么办?很简单!
step1:查找误删的分支上次提交的commit id
使用命令 git log -g
step2:用上一步查找到的commit id 恢复分支即可
使用命令 git branch 新的分支名 + commit id
PS: git brache xxxx 3eac14d05bc1264cda54a7c21f04c3892f32406a
step3: 切换到xxxx分支即可
13. base64和png文件间的互转
1)用nodejs,将base64转化成png文件
const fs = require('fs');
const path = 'xxx/'+ Date.now() +'.png';
const base64 = data.replace(/^data:image\/\w+;base64,/, "");
const dataBuffer = new Buffer(base64, 'base64');
fs.writeFile(path, dataBuffer, function(err){
if(err){
console.log(err);
}else{
console.log('写入成功!');
}
})
2)实现一下将png文件,转化成base64
const fs = require("fs");
const util = require("util");
const imageData = await util.promisify(fs.readFileSync(fileUrl));
const imageBase64 = imageData.toString("base64");
const imagePrefix = "data:image/png;base64,";
console.log(imagePrefix + imageBase64);
14. 运维
1)对于使用 yarn 安装的插件,如果不被识别,则把以下路径添加到系统的环境变量Path中,然后重开控制台即可:
C:\Users\用户名\AppData\Local\Yarn\Data\global\node_modules\.bin
C:\Users\用户名\AppData\Local\Yarn\bin
如果用npm安装yarn之后,yarn命令本身不被识别,则添加
C:\Users\用户名\AppData\Roaming\npm\node_modules\yarn\bin 到系统的环境变量Path中。
以上路径,可通过 npm bin -g、yarn global dir、yarn global bin 等获得。
2)Error: Cannot find module '.../lib/node_modules/pm2/lib/ProcessContainerFork.js'
rm -rf ~/.pm2
来源:CSDN
作者:ajrm0925
链接:https://blog.csdn.net/ajrm0925/article/details/104465650