目录
前言
web安全篇
1.如何防范XSS攻击
XSS攻击原理:
- 攻击者在网页中插入恶意的<script>代码,当用户浏览器时,脚本将用户的Cookie/Token发给攻击者
XXS一般有两种类型:
- 存储型:恶意脚本存到数据库中(评论区),所有看评论的人都会被攻击
- URL型:脚本嵌入在URL参数里,只有点击了链接的人才会被攻击
防御措施:
- 转义(前端做) :把"< "变成"< ",把"> "变成">"
- CSP策略(后端做):在HTTP Header中设置白名单,只允许加载那个域名的JS,其它域名的JS不执行
- HttpOnly Cookie(后端做):禁止JS读取Cookie
2.如何防范CSRF攻击
CSRF攻击原理:
- 用户登录了A网站(浏览器存储了A网站的Cookie),攻击者诱导用户点击B网站(钓鱼网站),B网站偷偷向A网站发送一个请求,此时这个请求会带上A网站的Cookie,那么攻击者就会获取到A网站的Cookie
防御措施:
- SameSIte Cookie:设置SameSite=true或Lax(Chrom浏览器默认开启Lax)
- CSRF Token:登陆后服务器发给前端一个Token,前端每次发送POST请求都要在Header里带上这个Token,攻击者拿不到这个Token,伪造的请求就会失败
- 验证Referer/Origin:后端检查请求是从哪里发出来的
代码手写篇
1.函数柯里化
柯里化就像是bind()返回一个函数,这个函数会检查此时传入的参数,如果传入的参数不够则返回带有已传参数的函数,否则执行函数
javascript
function curry(fn) {
return function curried(...args) {
if(args.length >= fn.length) {
return fn.apply(this, args);
}
else {
return function (...args2) {
return curried.apply(this, [...args, ...args2]);
}
}
}
}
function sum(a, b, c) {
return a + b + c;
}
const curriedSum = curry(sum);
console.log("标准柯里化调用形式(1个1个的调用):",curriedSum(1)(2)(3));
console.log("一次调用多个参数的柯里化形式:",curriedSum(1, 2)(3));
console.log("一次调用多个参数的柯里化形式:",curriedSum(1)(2, 3));
console.log("一次调用所有参数的柯里化形式:",curriedSum(1, 2, 3));
结果:

2.手写带并发限制的调度器
场景:
有 100 个请求,但我只允许同时发送 2 个。发完一个,立马补进来一个。保持"池子"里始终有 2 个在跑
javascript
class Scheduler {
constructor(limit) {
this.limit = limit;
this.count = 0;
this.queue = [];
}
add(promiseCreator) {
return new Promise((resolve, reject) => {
this.queue.push({
creator: promiseCreator,
resolve,
reject
});
this.run();
})
}
run() {
if (this.queue.length === 0 || this.count >= this.limit) {
return;
}
const { creator, resolve, reject } = this.queue.shift();
this.count++;
creator()
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
})
.finally(() => {
this.count--;
this.run();
})
}
}
const timeout = (time) => new Promise(resolve => {
setTimeout(resolve, time);
});
const scheduler = new Scheduler(2);
const addTask = (time, order) => {
scheduler.add(() => timeout(time))
.then(() => console.log(`任务 ${order} 完成`));
};
addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');
结果:
