You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**函数的作用域在函数创建时就已经确定了。**当函数创建时,会有一个名为 [[scope]] 的内部属性保存所有父变量对象到其中。当函数执行时,会创建一个执行环境,然后通过复制函数的 [[scope]] 属性中的对象构建起执行环境的作用域链,然后,变量对象 VO 被激活生成 AO 并添加到作用域链的前端,完整作用域链创建完成:
let const 块级作用域 箭头函数 词法this Class 解构,剩余运算符,Promise等,往这些方面展开。
手写函数防抖和函数节流
节流throttle
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
function throttle(fn, delay) {
let flag = true,
timer = null
return function(...args) {
let context = this
if(!flag) return
flag = false
clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(context,args)
flag = true
},delay)
}
}
400 Bad Request:客户端请求有语法错误,服务器无法理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务
404 Not Found:请求资源不存在。比如,输入了错误的url
415 Unsupported media type:不支持的媒体类型
5xx:服务器端错误,服务器未能实现合法的请求。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常
前言
开门见山,这篇文章,适合初级前端,如果你还在校招的话,或者还在求职的话,可以看看本文,找一找灵感,希望对你们有帮助呀。
先说一下最近个人情况:2020年8月底已经拿到
网易有道offer
, 这算是我的第一份web前端工作吧,一直以来都是自学前端的,走过很多的弯路,之前的技术栈是Vue.js,目前往react方向走。这是我的网易面经👉「面经」你可能需要的三轮网易面经
我的感受就是,自己一边梳理知识点,一边总结归纳,收获可能更大,所以打算把我梳理的部分分享出来,篇幅有点长,大家见谅呀。
覆盖的点不是很全,分享给你们,希望你们秋招一切顺利,offer收割机❤️❤️❤️
HTML系列
你是如何理解 HTML 语义化的?
让页面内容结构化,它有如下优点
如:
可以跟面试官讲的更具体一点👇
第一个是荒野阶段,那时候前端的代码主要是后台来写的,所以那个时候写的代码主要是用table来布局的。
第二阶段---美工阶段,这个时候就有专门的人来前端代码了,这个阶段的布局主要是DIV+CSS布局,但是呢有一个问题,就是不够语义化。
第三个阶段-->> 前端阶段,也就是利用具有语义的标签,比如p,h1,h2,article,header,nav,main,aside,footer这些标签,使用这些正确的标签,可以表达正确的内容,也利于开发和维护。
meta viewport 是做什么用的,怎么写?
通常viewport是指视窗、视口。浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域。在移动端和pc端视口是不同的,pc端的视口是浏览器窗口区域,而在移动端有三个不同的视口概念:布局视口、视觉视口、理想视口
meta有两个属性name 和 http-equiv
name
keywords(关键字) 告诉搜索引擎,你网页的关键字
description(网站内容描述) 用于告诉搜索引擎,你网站的主要内容。
viewport(移动端的窗口) 后面介绍
robots(定义搜索引擎爬虫的索引方式) robots用来告诉爬虫哪些页面需要索引,哪些页面不需要索引
author(作者)
generator(网页制作软件)
copyright(版权)
http-equiv
有以下参数:
content-Type 设定网页字符集
//旧的HTML,不推荐
//HTML5设定网页字符集的方式,推荐使用UTF-8
X-UA-Compatible(浏览器采用哪种版本来渲染页面)
//指定IE和Chrome使用最新版本渲染当前页面
cache-control(请求和响应遵循的缓存机制)
expires(网页到期时间)
你用过哪些 HTML 5 标签?
canvas画布
video
autoplay 布尔属性;视频马上自动开始播放,不会停下来等着数据载入结束。
controls 提供用户控制,允许用户控制视频的播放,包括音量,跨帧,暂停/恢复播放。
loop 布尔属性;指定后,会在视频结尾的地方,自动返回视频开始的地方。
track标签表示的是字幕
poster 表示的是封面
H5 是什么?-->>移动端页面
h5一般指的是开一个WebView来加载页面吧,
WebView是一种控件,它基于webkit引擎,因此具备渲染Web页面的功能。
基于Webview的混合开发,就是在 Anddroid (安卓)/(苹果)原生APP里,通过WebView控件嵌入Web页面。
很多APP都是外边套原生APP的壳,内容是H5页面(基于html+css+js的Web页面)。现在的移动端混合开发软件,如果对于交互渲染要求不是特别高的项目,基本都是这么玩的。
WebView作用
HTML5新特性:
增加
拖放API
、地理定位
、SVG绘图
、canvas绘图
、Web Worker
、WebSocket
区分普通显示屏和高清屏
并给出了如下CSS设计方案:
服务端用nginx对图片进行处理
想要什么样尺寸的图片自己裁切,我们提供了按比例缩放和自定尺寸的裁切方法,地址后拼接字符串就行。
使用更小更快更强,新一代图片格式 WebP
在实测中,webp 格式比 jpg 格式减小约 20%。这对优化用户体验,减少CDN带宽消耗有很好的效果。
如何判断呢
我想到一个解决的方案,就是通过User-Agent信息,可以拿到你的浏览器信息,通过对你的浏览器分类,支持webp放在白名单里,不支持的则为黑名单。判断为白名单,则直接调用,返回webp格式图片;反之,则显示原图。
DOM
事件冒泡
事件会从最内层的元素开始发生,一直向上传播,直到document对象。
因此上面的例子在事件冒泡的概念下发生click事件的顺序应该是
p -> div -> body -> html -> document
事件捕获
与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。
上面的例子在事件捕获的概念下发生click事件的顺序应该是
document -> html -> body -> div -> p
所以从上面的图片来看👉1-5是捕获过程,5-6是目标阶段,6-10是冒泡阶段
addEventListener
addEventListener方法用来为一个特定的元素绑定一个事件处理函数,是JavaScript中的常用方法。
重点来看看第三个参数
useCapture
所以我们通常来说,默认第三个参数不写的话,是按照事件句柄在冒泡执行的。
attachEvent
兼容IE的写法,默认是事件冒泡阶段调用处理函数,写事件名时候要加上"on"前缀("onload"、"onclick"等)。
事件代理
利用事件流的特性,我们可以使用一种叫做事件代理的方法,其实利用的就是事件冒泡的机制。
js代码
更加规范的写法👇
阻止事件冒泡和默认事件
实现一个可以拖拽的DIV
分割线-—---
CSS系列
两种盒模型分别说一下
也就是标准盒模型写起来更方便,也更规范吧。
盒模型分为标准盒模型和怪异盒模型(IE模型)
content-box
尺寸计算公式:
width
= 内容的宽度height
= 内容的高度宽度和高度的计算值都不包含内容的边框(border)和内边距(padding)。
border-box
尺寸计算公式:
width = border + padding + 内容的宽度
height = border + padding + 内容的高度
注意:如果你在设计页面中,发现内容区被撑爆了,那么就先检查一下border-sizing是什么,最好在引用reset.css的时候,就对border-sizing进行统一设置,方便管理
如何垂直居中?
16种方法实现水平居中垂直居中
水平局中
内联元素,宽度默认就是内容的宽度,只需要给父级添加text-align
块级元素,将它的margin-left和margin-right设置为auto,并且块级元素一定要设置宽度,否则元素默认为100%宽度,不需要居中。
两个以上的水平局中,可以将其设置为
display:inline-block
,在设置父级text-align垂直局中
内联元素,第一种实用的是flex布局,这里局中的值得是相对于父盒子
第二种,这里面指的局中是相对于自身而言的
块级元素
宽高确定情况下,实用 position absolute + 负margin
宽高不确定的情况下,实用position absolute + transform
垂直水平局中
子元素宽高确定的情况下,使用position absolute + 负margin
子元素宽高不确定的,使用position absolute + transform
当然了flex布局也是可以解决问题的,下面就介绍👇
两列布局
左列定宽,右列自适应
float+margin
左列自适应,右列定宽
float+overflow
css代码👇
三列布局
两列定宽,一列自适应
使用float+margin实现
css代码
间列自适应宽度,旁边两侧固定宽度
双飞翼布局
实现步骤
html部分
css部分
flex 怎么用,常用属性有哪些?
flex 的核心的概念就是 容器 和 轴。
父容器
justify-content 项目在主轴上的对齐方式
align-items 定义项目在侧轴上如何对齐
子容器
align-self 单个项目对齐方式
flex:前面三个属性的简写 是flex-grow flex-shrink flex-basis的简写
flex: 0 1 auto; 默认主轴是row,那么不会去放大比例,如果所有的子元素宽度和大于父元素宽度时,就会按照比例的大小去砍掉相应的大小。
轴
flex-direction 决定主轴的方向 即项目的排列方向
row | row-reverse | column | column-reverse
BFC 是什么?
深入理解BFC和外边距合并(Margin Collapse)
BFC全称是Block Formatting Context,即块格式化上下文。
BFC
就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。下列方式会创建块格式化上下文:
需要背的条件👇
BFC布局规则
选择器优先级
css常用选择器
css选择器权重
!important -> 行内样式 -> #id -> .class -> 元素和伪元素 -> * -> 继承 -> 默认
CSS新特性
transition
transform
animation
清除浮动说一下
第一种用伪元素
第二种给父容器添加 overflow:hidden 或者 auto 样式
三种地位方案
在定位的时候,浏览器就会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。定位时,有三种定位方案,分别是常规流,浮动已经绝对定位。
常规流(Normal flow)
position
为static
或relative
,并且float
为none
时会触发常规流;position: static
,盒的位置是常规流布局里的位置;position: relative
,盒偏移位置由这些属性定义top
,bottom
,left
andright
。即使有偏移,仍然保留原有的位置,其它常规流不能占用这个位置。浮动(Floats)
绝对定位(Absolute positioning)
top
,bottom
,left
及right
;position
为absolute
或fixed
,它是绝对定位元素;position: absolute
,元素定位将相对于最近的一个relative
、fixed
或absolute
的父元素,如果没有则相对于body
;获取DOM
Attribute与Property
attribute:是HTML标签上的某个属性,如id、class、value等以及自定义属性
property:是js获取的DOM对象上的属性值,比如a,你可以将它看作为一个基本的js对象。
路由规则
可以在不刷新页面的前提下动态改变浏览器地址栏中的URL地址,动态修改页面上所显示资源。
window.history的方法和属性
back()
forward()
go()
HTML5 新方法:添加和替换历史记录的条目
pushState()
state
: 一个于指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数中。如果不需要这个对象,此处可以填null。title
: 新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。url
: 新的网址,必须与前页面处在同一个域。浏览器的地址栏将显示这个网址。replaceState
popstate
事件,提供了单页应该的另一种路由方式。popstate
事件:历史记录发生改变时触发基于hash(location.hash+hashchange事件)
我们知道location.hash的值就是url中
#
后面的内容,如http://www.163.com#something
。此网址中,location.hash='#something'。
hash满足以下几个特性,才使得其可以实现前端路由:
如此一来,我们就可以在hashchange事件里,根据hash值来更新对应的视图,但不会去重新请求页面,同时呢,也在history里增加了一条访问记录,用户也仍然可以通过前进后退键实现UI的切换。
触发hash值的变化有2种方法👇
JS系列
JS基础是最重要的一个环节,所以这个专题,我也是梳理总结了很多,毕竟这个是灵魂嘛,那接下来我把我梳理的文章也总结一遍,然后我复习的部分内容也梳理出来了。
往期文章总结
介绍一下js数据类型
基本数据类型,Number、String、Boolean、Undefined、Null、Symbol ,BigInt。
比如Symbol提出是为了解决什么问题?可以往全局变量冲突讲。
比如BigInt,解决的问题是大数问题,超过了安全数,怎么办?
引用数据类型,数组,对象,函数。
可以试着往它们存储问题上面答,基本数据类型的值直接保存在栈中,而复杂数据类型的值保存在堆中,通过使用在栈中保存对应的指针来获取堆中的值。
Number.isFinite & isFinite区别
某种程度上,都是检测有限性的值。两者区别在于,isFinite函数强制将一个非数值的参数转换成数值,如果能转换成数值,然后再去判断是否是有限的。
Number.isFinite()检测有穷性的值,这个方法不会强制将一个非数值的参数转换成数值,这就意味着,只有数值类型的值,且是有穷的(finite),才返回
true
。isNaN 和 Number.isNaN 函数的区别?
我们来看看Number.isNaN
什么是可迭代对象
如何判断一个类型是不是可迭代对象
结论
arguments对象了解吗
这个arguments有个易错点,容易忽略的点。
首先我们看下它的定义:
arguments
对象是所有(非箭头)函数中都可用的局部变量。此对象包含传递给函数的每个参数,第一个参数在索引0处。arguments
对象不是一个Array
。它类似于Array
,但除了length属性和索引元素之外没有任何Array
属性。转换成数组👇
易错点👇
当非严格模式中的函数没有包含剩余参数、默认参数和解构赋值,那么
arguments
对象中的值会跟踪参数的值(反之亦然),看几个题目懂了这里arguments就会跟踪a变量👇
当非严格模式中的函数有包含剩余参数、默认参数和解构赋值,那么
arguments
对象中的值不会跟踪参数的值(反之亦然)。相反,arguments
反映了调用时提供的参数:并且
并且
原型
__proto__
称为隐式原型。__proto__
这个指针我们应该获取这个值,但是浏览器中都实现了__proto__
属性来让我们访问这个属性,但是我们最好不要使用这个属性,因为它不是规范中规定的。举个例子👇
为什么我们新建的对象可以使用toString()方法,这是因为我们访问一个对象的属性时,首先会在这个对象身上找,如果没有的话,我们会通过这个对象的
__proto__
找到该对象的原型,然后在这个原型对象中找,这个原型对象又没有的话,就这样子通过一直找下去,这也就是原型链概念。直到找到原型链的尽头也就是Object.prototype。js 获取原型的方法?
假设Demo是一个对象,那么有三种方式👇
__proto__
获取对象属性的方法
length
属性for of 和 for in区别
for in
我们直接从一段代码来看
有哪些缺陷呢👇
for of
小结
作用域链
作用域 规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做 作用域链。
**函数的作用域在函数创建时就已经确定了。**当函数创建时,会有一个名为
[[scope]]
的内部属性保存所有父变量对象到其中。当函数执行时,会创建一个执行环境,然后通过复制函数的[[scope]]
属性中的对象构建起执行环境的作用域链,然后,变量对象VO
被激活生成AO
并添加到作用域链的前端,完整作用域链创建完成:所以闭包,可以说是作用域链的另外一种表示形式。
闭包的应用
闭包的应用比较典型是定义模块,我们将操作函数暴露给外部,而细节隐藏在模块内部
ES6 语法知道哪些,分别怎么用?
let const 块级作用域 箭头函数 词法this Class 解构,剩余运算符,Promise等,往这些方面展开。
手写函数防抖和函数节流
节流throttle
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
防抖
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
手写AJAX
数组去重
手写bind函数
实现call
实现一个快排
数组的扁平化
深拷贝
实现高阶函数柯里化
寄生组合式继承
this
this 永远指向最后调用它的那个对象
主要有下面几个规则
ECMAScript6 怎么写 class,为什么会出现 class 这种东西?
哪些操作会造成内存泄漏?
相关知识点:
Object.is()使用过吗?跟 === 和 == 区别
JS事件循环机制了解吗
微任务包括了 promise 的回调、node 中的 process.nextTick 、对 Dom 变化监听的 MutationObserver。
宏任务包括了 script 脚本的执行、setTimeout ,setInterval ,setImmediate 一类的定时事件,还有如 I/O 操作、UI 渲染等。
立即执行函数是什么?
声明一个函数,并马上调用这个匿名函数就叫做立即执行函数;也可以说立即执行函数是一种语法,让你的函数在定义以后立即执行;
写法👇
作用:
什么是 JSONP,什么是 CORS,什么是跨域?
这个我有篇文章已经总结啦,所以这里就直接跳到对应文章吧,传送门
发布订阅者模式
下面是测试数据
浏览器相关
这个浏览器专题的话,我之前也总结过啦,所以这里就贴出地址,有兴趣的可以去补一补基础知识,大部分的知识点下面也提及到了,就不单独拿出来梳理啦👇
往期文章总结
「查缺补漏」送你18道浏览器面试题(780+👍)
「浏览器工作原理」写给女友的秘籍-浏览器组成&网络请求篇(1.2W字)(270+👍)
「浏览器工作原理」写给女友的秘籍-渲染流程篇(1.1W字)(280+👍)
Cookie V.S. LocalStorage V.S. SessionStorage V.S. Session
其中的一个相同点,就是它们保存在浏览器端,且同源的。
那么不同点是哪些呢👇
异同点
操作方式
接下来我们来具体看看如何来操作
localStorage
和sessionStorage
接着进入相同的域名时就能拿到相应的值👇
从这里可以看出,
localStorage
其实存储的都是字符串,如果是存储对象需要调用JSON
的stringify
方法,并且用JSON.parse
来解析成对象。应用场景
logo
,存储Base64
格式的图片资源等;什么是 XSS?如何预防?
XSS 全称是
Cross Site Scripting
,为了与CSS
区分开来,故简称XSS
,翻译过来就是“跨站脚本”。XSS是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。
最开始的时候,这种攻击是通过跨域来实现的,所以叫“跨域脚本”。发展到现在,往HTML文件中中插入恶意代码方式越来越多,所以是否跨域注入脚本已经不是唯一的注入手段了,但是 XSS 这个名字却一直保留至今。
注入恶意脚本可以完成这些事情:
一般的情况下,XSS攻击有三种实现方式
存储型 XSS 攻击
存储型 XSS 攻击大致步骤如下:
比如常见的场景:
在评论区提交一份脚本代码,假设前后端没有做好转义工作,那内容上传到服务器,在页面渲染的时候就会
直接执行
,相当于执行一段未知的JS代码。这就是存储型 XSS 攻击。反射型 XSS 攻击
反射型 XSS 攻击指的就是恶意脚本作为**「网络请求的一部分」**,随后网站又把恶意的JavaScript脚本返回给用户,当恶意 JavaScript 脚本在用户页面中被执行时,黑客就可以利用该脚本做一些恶意操作。
举个例子:
如上,服务器拿到后解析参数query,最后将内容返回给浏览器,浏览器将这些内容作为HTML的一部分解析,发现是Javascript脚本,直接执行,这样子被XSS攻击了。
这也就是反射型名字的由来,将恶意脚本作为参数,通过网络请求,最后经过服务器,在反射到HTML文档中,执行解析。
主要注意的就是,「服务器不会存储这些恶意的脚本,这也算是和存储型XSS攻击的区别吧」。
基于 DOM 的 XSS 攻击
基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。具体来讲,黑客通过各种手段将恶意脚本注入用户的页面中,在数据传输的时候劫持网络数据包
常见的劫持手段有:
阻止 XSS 攻击的策略
以上讲述的XSS攻击原理,都有一个共同点:让恶意脚本直接在浏览器执行。
针对三种不同形式的XSS攻击,有以下三种解决办法
对输入脚本进行过滤或转码
对用户输入的信息过滤或者是转码
举个例子👇
转码后👇
这样的代码在 html 解析的过程中是无法执行的。
当然了对于
<script>
、<img>
、<a>
等关键字标签也是可以过来的,效果如下👇最后什么都没有剩下了
利用 CSP
该安全策略的实现基于一个称作
Content-Security-Policy
的 HTTP 首部。可以移步MDN,有更加规范的解释。我在这里就是梳理一下吧。
CSP,即浏览器中的内容安全策略,它的核心思想大概就是服务器决定浏览器加载哪些资源,具体来说有几个功能👇
利用 HttpOnly
由于很多 XSS 攻击都是来盗用 Cookie 的,因此还可以通过使用 HttpOnly 属性来保护我们 Cookie 的安全。这样子的话,JavaScript 便无法读取 Cookie 的值。这样也能很好的防范 XSS 攻击。
通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的,下面是打开 Google 时,HTTP 响应头中的一段:
总结
XSS
攻击是指浏览器中执行恶意脚本, 然后拿到用户的信息进行操作。主要分为存储型
、反射型
和文档型
。防范的措施包括:<script>
、<img>
、<a>
标签除了以上策略之外,我们还可以通过添加验证码防止脚本冒充用户提交危险操作。而对于一些不受信任的输入,还可以限制其输入长度,这样可以增大 XSS 攻击的难度。
什么是 CSRF?如何预防?
CSRF 英文全称是
Cross-site request forgery
,所以又称为“跨站请求伪造”,是指黑客引诱用户打开黑客的网站,在黑客的网站中,利用用户的登录状态发起的跨站请求。简单来讲,CSRF 攻击就是黑客利用了用户的登录状态,并通过第三方的站点来做一些坏事。一般的情况下,点开一个诱导你的链接,黑客会在你不知情的时候做哪些事情呢
1. 自动发起 Get 请求
黑客网页里面可能有一段这样的代码👇
在受害者访问含有这个img的页面后,浏览器会自动向
http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker
发出一次HTTP请求。bank.example
就会收到包含受害者登录信息的一次跨域请求。2. 自动发起 POST 请求
黑客网页中有一个表单,自动提交的表单👇
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。
同样也会携带相应的用户 cookie 信息,让服务器误以为是一个正常的用户在操作,让各种恶意的操作变为可能。
3. 引诱用户点击链接
这种需要诱导用户去点击链接才会触发,这类的情况比如在论坛中发布照片,照片中嵌入了恶意链接,或者是以广告的形式去诱导,比如:
点击后,自动发送 get 请求,接下来和
自动发 GET 请求
部分同理。以上三种情况,就是CSRF攻击原理,跟XSS对比的话,CSRF攻击并不需要将恶意代码注入HTML中,而是跳转新的页面,利用服务器的验证漏洞和用户之前的登录状态来模拟用户进行操作
防护策略
其实我们可以想到,黑客只能借助受害者的
**cookie**
骗取服务器的信任,但是黑客并不能凭借拿到cookie,也看不到 cookie的内容。另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。用户操作限制——验证码机制
方法:添加验证码来识别是不是用户主动去发起这个请求,由于一定强度的验证码机器无法识别,因此危险网站不能伪造一个完整的请求。
1. 验证来源站点
在服务器端验证请求来源的站点,由于大量的CSRF攻击来自第三方站点,因此服务器跨域禁止来自第三方站点的请求,主要通过HTTP请求头中的两个Header
这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容。
服务器可以通过解析这两个Header中的域名,确定请求的来源域。
其中,Origin只包含域名信息,而Referer包含了
具体
的 URL 路径。在某些情况下,这两者都是可以伪造的,通过
AJax
中自定义请求头即可,安全性略差。2. 利用Cookie的SameSite属性
可以看看MDN对此的解释
SameSite
可以设置为三个值,Strict
、Lax
和None
。Strict
模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com
网站只能在sanyuan.com
域名当中请求才能携带 Cookie,在其他网站请求都不能。Lax
模式,就宽松一点了,但是只能在get 方法提交表单
况或者a 标签发送 get 请求
的情况下可以携带 Cookie,其他情况均不能。3. CSRF Token
前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。
那么我们可以使用Token,在不涉及XSS的前提下,一般黑客很难拿到Token。
可以看看这篇文章,将了Token是怎么操作的👉彻底理解cookie,session,token
Token(令牌)做为Web领域验证身份是一个不错的选择,当然了,JWT有兴趣的也可以去了解一下。
Token步骤如下:
第一步:将CSRF Token输出到页面中
第二步:页面提交的请求携带这个Token
第三步:服务器验证Token是否正确
非常感兴趣的,可以仔细去阅读一下相关的文章,Token是如何加密的,又是如何保证不被攻击者获取道。
总结
CSRF(Cross-site request forgery), 即跨站请求伪造,本质是冲着浏览器分不清发起请求是不是真正的用户本人,所以防范的关键在于在请求中放入黑客所不能伪造的信息。从而防止黑客伪造一个完整的请求欺骗服务器。
防范措施:验证码机制,验证来源站点,利用Cookie的SameSite属性,CSRF Token
JS 垃圾回收机制
这部分的知识点,基本上看别人写的翻译,然后按照别人的思路去完成的,所以这里就推荐一篇我看的文章吧,个人觉得写的还是挺好的,所以有兴趣的可以了解一下,下面的文章👇
简单了解JavaScript垃圾回收机制
计算机网络部分
这个专题也十分的重要,面试大厂的话,这个你得会,不问就不要紧,但是问到你的话,必须的会,我之前梳理过一篇文章,效果还不错,这里分享给大家👇
往期文章
HTTP 状态码知道哪些?分别什么意思?
状态码:由3位数字组成,第一个数字定义了响应的类别
1xx:指示信息,表示请求已接收,继续处理
2xx:成功,表示请求已被成功接受,处理。
3xx:重定向
4xx:客户端错误
5xx:服务器端错误,服务器未能实现合法的请求。
长轮询和短轮询
短轮询
短轮询(Polling)的实现思路就是浏览器端每隔几秒钟向服务器端**发送http请求,服务端在收到请求后,不论是否有数据更新,都直接进行响应。**在服务端响应完成,就会关闭这个Tcp连接。
长轮询
客户端发送请求后服务器端不会立即返回数据,服务器端会阻塞请求连接不会立即断开,直到服务器端有数据更新或者是连接超时才返回,客户端才再次发出请求新建连接、如此反复从而获取最新数据。
HTTP 缓存有哪几种?
浏览器缓存是性能优化的一个重要手段,对于理解缓存机制而言也是很重要的,我们来梳理一下吧👇
强缓存
强缓存两个相关字段,「Expires」,「Cache-Control」。
「强缓存分为两种情况,一种是发送HTTP请求,一种不需要发送。」
首先检查强缓存,这个阶段**不需要发送HTTP请求。**通过查找不同的字段来进行,不同的HTTP版本所以不同。
Expires
Expires
即过期时间,时间是相对于服务器的时间而言的,存在于服务端返回的响应头中,在这个过期时间之前可以直接从缓存里面获取数据,无需再次请求。比如下面这样:表示该资源在2020年
7月29日11:10:23
过期,过期时就会重新向服务器发起请求。这个方式有一个问题:「服务器的时间和浏览器的时间可能并不一致」,所以HTTP1.1提出新的字段代替它。
Cache-Control
HTTP1.1版本中,使用的就是该字段,这个字段采用的时间是过期时长,对应的是max-age。
上面代表该资源返回后6000秒,可以直接使用缓存。
当然了,它还有其他很多关键的指令,梳理了几个重要的👇
注意点:
协商缓存
强缓存失效后,浏览器在请求头中携带响应的
缓存Tag
来向服务器发送请求,服务器根据对应的tag,来决定是否使用缓存。缓存分为两种,「Last-Modified」 和 「ETag」。两者各有优势,并不存在谁对谁有
绝对的优势
,与上面所讲的强缓存两个Tag所不同。Last-Modified
这个字段表示的是**「最后修改时间」**。在浏览器第一次给服务器发送请求后,服务器会在响应头中加上这个字段。
浏览器接收到后,「如果再次请求」,会在请求头中携带
If-Modified-Since
字段,这个字段的值也就是服务器传来的最后修改时间。服务器拿到请求头中的
If-Modified-Since
的字段后,其实会和这个服务器中该资源的最后修改时间
对比:ETag
ETag是服务器根据当前文件的内容,对文件生成唯一的标识,比如MD5算法,只要里面的内容有改动,这个值就会修改,服务器通过把响应头把该字段给浏览器。
浏览器接受到ETag值,会在下次请求的时候,将这个值作为**「If-None-Match」**这个字段的内容,发给服务器。
服务器接收到**「If-None-Match」后,会跟服务器上该资源的「ETag」**进行比对👇
两者对比
Last-Modified
优于ETag
,Last-Modified
记录的是时间点,而Etag
需要根据文件的MD5算法生成对应的hash值。ETag``Last-Modified``ETag``Last-Modified
最后,「如果两种方式都支持的话,服务器会优先考虑ETag」。
缓存位置
接下来我们考虑使用缓存的话,缓存的位置在哪里呢?
浏览器缓存的位置的话,可以分为四种,优先级从高到低排列分别👇
Service Worker
这个应用场景比如PWA,它借鉴了Web Worker思路,由于它脱离了浏览器的窗体,因此无法直接访问DOM。它能完成的功能比如:
离线缓存
、消息推送
和网络代理
,其中离线缓存
就是**「Service Worker Cache」**。Memory Cache
指的是内存缓存,从效率上讲它是最快的,从存活时间来讲又是最短的,当渲染进程结束后,内存缓存也就不存在了。
Disk Cache
存储在磁盘中的缓存,从存取效率上讲是比内存缓存慢的,优势在于存储容量和存储时长。
Disk Cache VS Memory Cache
两者对比,主要的策略👇
内容使用率高的话,文件优先进入磁盘
比较大的JS,CSS文件会直接放入磁盘,反之放入内存。
Push Cache
推送缓存,这算是浏览器中最后一道防线吧,它是
HTTP/2
的内容。具体我也不是很清楚,有兴趣的可以去了解。总结
Cache-Control
, 尝鲜,看强缓存是否可用If-Modified-Since
或者If-None-Match
字段检查资源是否更新GET 和 POST 的区别
首先,我们的知道区别只是语义上有区别而已,但是面试的时候,肯定不能这么回答的。
Webpack
这个面试也是会经常考的一部分了,所以掌握它还是很有必要的,我是从0到1配过它的,所以这里我就没有梳理笔记了,嗯,下面就推荐两个文章,希望看完可以对你们有帮助。
实打实的从0到1配置webpack👇
「一劳永逸」由浅入深配置webpack4
针对面试的👇
关于webpack的面试题总结
算法与数据结构
这个专题,我目前总结了三个板块,速度有点慢,不过面试初级前端的话,应该是没有问题的,需要了解的小伙伴可以看看我梳理的三篇👇
往期文章
如果你跟我一样,对算法也有所热爱的话,我们可以互相讨论下算法,或者关注我哒,我会一直更新算法哒。
模块化
将一个复杂的程序依据特定的规则(规范)封装成几个文件,然后将其组合在一起,这些只是向外暴露一些接口,或者方法,与其他模块进行通信,这样子叫做是模块化的过程。
为什么要模块化,目的在于减少复杂性,减少它们相互之间的功能关系。使每个模块功能单一。
模块化好处
CommomJS
CommonJS定义了两个主要概念:
require
函数,用于导入模块module.exports
变量,用于导出模块require
导入,代码很简单,
let {count,addCount}=require("./utils")
就可以了。require
的第一步是解析路径获取到模块内容:fs
,就直接返回模块/
,./
等等,则拼接出一个绝对路径,然后先读取缓存require.cache
再读取文件。如果没有加后缀,则自动加后缀然后一一识别。.js
解析为JavaScript 文本文件.json
解析JSON对象.node
解析为二进制插件模块require.cache
之中,所以多次加载require
,得到的对象是同一个。module
然后根据require执行代码时需要加上的,那么实际上我们的代码长成这样:
ES6模块与CommonJS的区别
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
import
,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。换句话说,ES6 的import
有点像 Unix 系统的“符号连接”,原始值变了,import
加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
export
命令显式指定输出的代码,import
时采用静态命令的形式。即在import
时可以指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载”。模块化开发怎么做?
❤️ 感谢大家
如果你觉得这篇内容对你挺有有帮助的话:
前端UpUp
,定期为你推送好文。The text was updated successfully, but these errors were encountered: