前端安全-xss和csrf
csrf定义csrf: 跨站请求伪造 cross site Request forgery 或者简称xsrf。是指在挟持用户在当前已经登录的web应用程序当中执行非本意操作的攻击方法。另一个是xss cross site script 跨站脚本攻击,两者区别是 xss利用用户对网站的信任,csrf利用的是网站对用户信任
简单来说就是利用用户的登录态发起恶意请求利用用户的登录状态发起恶意请求
如何攻击的
如何防御遵循以下几种原则:1.get请求不对数据进行修改2.禁止第三方网站访问到用户cookie3.阻止第三方网站请求接口4.请求时附带验证信息,比如tocken或者验证码
具体措施
SameSite对cookie设置SameSite属性,设置之后cookie信息不会随着跨域请求发送,很大程度上减少CSRF攻击
验证referer在对需要防范csrf的请求中,我们阔以根据请求头中的referer属性来判断请求来源
Token服务器下发随机token,前端每次发请求携带token,后端验证token的有效性
防抓包使用https替换http(https还是通过http进行传输,只是信息 ...
算法基础: BFS和DFS
DFS 深度优先遍历全排列给定一个 没有重复 数字的序列,返回其所有可能的全排列。
12Input: nums = [1,2,3]Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
123456789101112131415161718var permute = function(nums) { var res = [] var path = [] var dfs = (path, nums) => { if (path.length === nums.length) { res.push(path) } for (let num of nums) { if (!path.includes(num)) { path.push(num) dfs(path.slice(), nums) path.pop() } } } ...
vue进阶: 依赖收集原理
观察者模式一对多关系解耦的行为设计模式,主要涉及两个角色,观察者和观察目标 观察者直接订阅观察目标,观察目标(订阅中心)做出通知,观察者就要进行处理
vue依赖收集 每个组件实例都会有相应的Watcher实,渲染组件的过程,会把属性记录为依赖,当我们操作数据的时候,依赖项的setter会被调用,从而通知Watcher重新计算,从而使得相关的组件得以更新。
Getter里进行依赖收集,当依赖的数据被更新时,会触发该数据的setter,setter里会触发render函数重新计算
依赖收集与观察者模式vue依赖收集的场景既是一对多,一个数据发生变更,多处用到该数据的地方都得处理。而且依赖的数据变了,即必须要做出处理。vue里,依赖的数据是观察目标(Dep, 订阅中心),依赖就是Dep视图、计算属性、侦听器等算是观察者(watcher),用到该数据的就是观察者(Watcher)
源码解析vue依赖收集三个角色Dep: 扮演观察目标的角色,每一个数据都会有一个Dep类的实例,内部有subs队列,保存着依赖本数据的观察者Watcher,当本数据变更时,调用实例dep.notify通知观 ...
数据结构与算法基础: 树和二叉搜索树
应用场景广泛,可惜我个小菜鸟几乎全跪!!!如何提高?
二叉树和二叉搜索树二叉树: 书中的节点最多只能有2个节点,一个是左侧子节点,一个是右侧子节点二叉搜索树(BST): 二叉树种的一种,但是只允许你在左侧存储比父节点小的值,右侧存储比父节点大的值
两颗相同的树题目:给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
答案:
1234567891011121314/** * @param {TreeNode} p * @param {TreeNode} q * @return {boolean} */var isSameTree = function(p, q) { if (p == null && q == null) { return true } if (p == null || q == null) { return false ...
数据结构进阶: 链表
链表还是没啥数据概念,多做做点题目,理解理解链表
反转链表题目12输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL
题解
迭代123456789101112131415/** * @param {ListNode} head * @return {ListNode} */var reverseList = function(head) { let current = head let pre = null while(current) { const next = current.next current.next = pre pre = current current = next } return pre};
两两交换链表中的节点题目给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的 ...
随笔: 35岁该何去何从
马上就到了35岁,还有五年的光阴,想抓住最后的年轻红利,大声喊出我们的口号:Formulation for decade, freedom forever.五年布局,百年自由
接下来的时间(3月底),重点关注
webpack编译相关
vue源码级别的面试题
栈和队列聚焦上面两项,为自由奋斗!!!
前端进阶: Promise.all/any/race/allSettled手写
Promise以下几个api,直接手写,便于理解。学习就是一个渐进的过程,第一遍看不懂,第二遍只能领略皮毛,后面再看,仔细品味,感觉还是不错的
Promise.all(Iterator)Promise.all() 方法会将多个 Promise 实例组合成一个新的 Promise 实例1.传入的参数必须可迭代2.传入的实例不一定是Promise,必须再用Promise.resolve()包装下3.组合后的Promise实例,只有当每个包含的Promise实例都解决才去解决(fulFilled),当然如果有一个Promise实例被拒绝的话,则合成的Promise会拒绝(rejected)
12345678910111213141516171819202122232425262728293031323334353637383940414243// 手写allvar p1 = Promise.resolve( 1 );var p2 = Promise.resolve( Promise.resolve( '111' ) );var p3 = Promise.reject('error')Prom ...
前端基础-手写async/await
手写之前先学习下async/await
asyncasync 函数是什么?一句话,它就是 Generator 函数的语法糖。异步的简写,用于申明一个函数是异步的,而await用于等待一个异步方法执行完成,await只能出现在async函数中。
123456789101112var getData = () => new Promise(resolve => setTimeout(() => resolve('data'), 3000))async function test() { const data = await getData() console.log('data: ', data); const data2 = await getData() console.log('data2: ', data2); return 'success'}test().then(res => console.log(res))// data: data// data2: data// success
换成generator函数就是
12 ...
前端进阶:loader和plugin插件学习
webpack loader和plugin配置项
npx webpack –mode=development
1234567891011121314151617181920module: { rules: [ // 转换 ES6 代码,解决浏览器兼容问题 { test: '/\.js$/', exclude: '/node_modules/', use: [ { loader: 'babel-loader' }, { loader: path.join(__dirname, '../loader/cpp-loader,js'), options: { log: 'hello loader' } } ] }, ]}
loader简单来说,loader就是一个nodejs模 ...
数据结构与算法基础-排序
感觉自己好磨蹭,1月3号建的文章题目,2个月之后还是没有深得精髓,对自己好失望!!
冒泡排序 bubbleSort123456789101112131415161718export const bubbleSort = (arr) => { const {length} = arr // let flag = false if (length < 2) { return arr } for(let i = 0; i < length; i ++) { // flag = false for(let j = 0; j < length - 1 - i; j ++) { if (arr[j] > arr[j + 1]) { swap(arr, j, j + 1) // flag = true } } // if (!flag) break } return ar ...