cookies、sessionStorage、localStorage 和 indexDB 的区别
- cookie是网站为了标示用户身份而储存在用户本地的数据
- 是否在http请求只能够携带
- cookie数据始终在同源的http请求中携带,跨域需要设置
withCredentials = true - sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
- cookie数据始终在同源的http请求中携带,跨域需要设置
- 存储大小:
- cookie数据大小不能超过
4k; - sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到
5M或更大,因不同浏览器大小不同;
- cookie数据大小不能超过
- 有效时间:
- cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
- localStorage 硬盘存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
- sessionStorage 存在内存中,数据在当前浏览器窗口关闭后自动删除
从输入一个 URL 地址到浏览器完成渲染的整个过程
- 浏览器地址栏输入 URL 并回车
- 浏览器查找当前 URL 是否存在缓存,并比较缓存是否过期
- DNS 解析 URL 对应的 IP
- 根据 IP 建立 TCP 连接(三次握手)
- 发送 http 请求
- 服务器处理请求,浏览器接受 HTTP 响应
- 浏览器解析并渲染页面
- 关闭 TCP 连接(四次握手) 渲染过程
- 根据HTML结构生成DOm树;
- 根据CSS生成CSSOM;
- 将DOM和CSSOM整合形成RenderTree;
- 根据RenderTree开始渲染和展示;
- 遇到
说说前端中的事件流
HTML中与JavaScript交互是通过事件驱动来实现的,例如鼠标点击事件onclick、页面的滚动事件onscroll等,可以向文档或者文档中的元素添加事件侦听器来预定事件。
什么是事件流:事件流描述的是从页面接收事件的顺序,DOM2级事件流包括下面几个阶段:
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段 addEventListener: 事件的监听器,这个方法接收三个参数:要处理的事件名,作为事件处理程序的函数、一个布尔值。最后这个布尔值参数如果是ture,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序;默认是false,因为IE只支持事件冒泡;
如何让事件先冒泡后捕获
在DOM标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对象相应的处理函数,监听到捕获事件,先暂缓执行,知道冒泡事件被执行后再执行捕获;
什么是事件代理(事件委托) 有什么好处
事件委托的原理:不给每个子节点单独设置事件监听器,而是设置在其父节点上,然后利用冒泡原理设置每个子节点。 优点:
- 减少内存消耗和 dom 操作,提高性能,在 JavaScript 中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的操作dom,那么引起浏览器重绘和回流的可能也就越多,页面交互的事件也就变的越长,这也就是为什么要减少dom操作的原因。每一个事件处理函数,都是一个对象,多一个事件处理函数,内存中就会被多占用一部分空间。如果要用事件委托,就会将所有的操作放到 js 程序里面,只对它的父级进行操作,与 dom 的操作就只需要交互一次,这样就能大大的减少与 dom 的交互次数,提高性能;
- 动态绑定事件,因为事件绑定在父级元素,所以新增的元素也能触发同样的事件
addEventListener 默认是捕获还是冒泡
- 默认是冒泡
- addEventListener第三个参数默认为 false 代表执行事件冒泡行为。
- 当为 true 时执行事件捕获行为。
apply call bind 区别
- 三者都可以改变函数的 this 对象指向。
- 三者第一个参数都是 this 要指向的对象,如果如果没有这个参数或参数为 undefined 或 null,则默认指向全局 window。
- 三者都可以传参,但是 apply 是数组,而 call 是参数列表,且 apply 和 call 是一次性传入参数,而 bind 可以分为多次传入。
- bind 是返回绑定 this 之后的函数,便于稍后调用;apply 、call 则是立即执行 。
- bind()会返回一个新的函数,如果这个返回的新的函数作为构造函数创建一个新的对象,那么此时 this 不再指向传入给 bind 的第一个参数,而是指向用 new 创建的实例
实现图片懒加载的思路
判断图片所在位置是否在可视区域内,图片移到可视区域内进行加载,提供三种判断方法:
offsetTop < clientHeight + scrollTop
element.getBoundingClientRect().top < clientHeight
`getBoundingClientRect: 用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。`
IntersectionObserver
`IntersectionObserver: 可以异步监听目标元素与其祖先或视窗(viewport)交叉状态的手段`
如何处理跨域
前端发起请求的地址是和页面地址一致的所以不存在跨域
- 在vue中可以使用porxy代理来解决
proxyTable: {
'/api': {
target: 'http://localhost:8083/',//设置你调用的接口域名和端口号 别忘了加http
changeOrigin: true, //這裡true表示实现跨域
pathRewrite: {
'^/api':'/'
//这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调
用'http://40.00.100.100:3002/user/add',直接写‘/api/user/add’即可
}
}
- 通过nginx进行转发
- JSONP:利用script标签可跨域的特点,在跨域脚本中可以直接回调当前脚本的函数
- CORS:服务器设置HTTP响应头中Access-Control-Allow-Origin值,解除跨域限制
JSONP的工作原理?
JSONP是一种非正式的传输协议,允许用户传递一个callback给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据。当GET请求从后台页面返回时,可以返回一段JavaScript代码,这段代码会自动执行,可以用来调用后台页面中的一个callback函数。
表单可以跨域吗?
表单提交是可以进行跨域的,不受浏览器的同源策略限制,估计是历史遗留的原因,也有可能是提交的结果js拿不到,所以不限制问题也不大。但是存在一个问题,就是csrf攻击(跨站请求伪造),因为可以自动带上cookie造成攻击成功,而cookie的新属性SameSite就能用来限制这种情况;
为什么说js是单线程,而不是多线程?
JavaScript的单线程,与他的用途有关。作为浏览器的脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这就决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假如JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时候的浏览器应该以哪个线程为准?
为甚typeof可以检测类型,有没有其他更好的方法?
typeof一般用于判断一个变量的类型,我们可以利用typeof判断number、string、object、boolean、function、undefined、symbol这七种类型,这种判断能帮助我们解决一些问题;js在底层存储变量的时候,会在变量的机器码的低位1-3位存储类型信息(000:对象,010:浮点数,100:字符串,110:布尔,1:整数),但是null所有的机器码均为0,直接被当做了对象来看待,这时候我们可以用**Object.prototype.toString.call()**来做判断;
使用js如何改变url,并且不刷新页面?
- 改变url的目的是让js拿到不同的参数,进行不同页面的渲染,其实就是vue-router的原理。
- 最简单的就是改变hash,改变hash并不会刷新页面,也会改变url,也能监听hashChange事件进行页面渲染。
- 还有一种就是使用history.pushState()方法,该方法也可以改变url然后不刷新页面,但是该方法并不能触发popstate事件,不过popState是我们手动触发的,还能不知道url改变了么,其实这时候并不需要监听popState我们就能够知道url改变拿到参数渲染页面。
实现一个js持续动画,有什么比较好的方法?
- 使用requestAnimationFrame。实现动画的效果比较多,js可以通过定时器来实现,css3也可以使用transition和animation来实现,html5中的canvas也可以实现。
- 除了这些就是我说的requestAnimationFrame,顾名思义就是请求动画帧;
- 使用requestAnimationFrame的优势在于由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿;
使用css3动画代替js动画有什么好处?
- 简单,声明式的动画描述比js模拟的动画好弄的多;
- 性能,使用js对DOM节点操作进行变换,会带来大量的重排、重绘,而css3动画可以比较好的规避这点,甚至可以利用CPU进行加速。
js自定义事件的使用与触发;
- 创建:
createEvent()、构造函数new Event()创建; - 监听:
elem.addEventListener('event', ()=>{}, false); - 触发:
elem.dispatchEvent('event'); - 在vue里面可以使用Vue.directive()来创建
OAuth2简述?
- OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们储存在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容;
- 应用场景:第三方应用授权登录,在APP或者网页介入一些第三方应用时,时常会需要用户登录另一个合作平台,比如QQ、微博、微信的授权登录;
- 用户访问客户端(指定重定向的URl,附上一个授权码) --> 客户端收到授权码,向认证服务器申请令牌,成功返回code授权码 --> 认证服务器核对了授权码和重定向的URL,确认无误后向客户端发送访问令牌和更新令牌。
使用JSX的优点?
JSX是JavaScript的一种扩展,为函调用和对象构造提供了语法糖。
- 改进开发人员的体验,代码更易读,因为它们更加形象;
- JSX执行更快,因为它在编译为JavaScript代码后进行了优化;
- JSX是类型安全的,在编译过程中就能发现错误;
- 使用JSX编写模板更加简单快速。
如何解决移动端1px问题?
- 使用边框图片
- 使用box-shadow实现
- 使用伪元素
.setOnePx{
position: relative;
&::after{
position: absolute;
content: '';
background-color: #e5e5e5;
display: block;
width: 100%;
height: 1px; /*no*/
transform: scale(1, 0.5);
top: 0;
left: 0;
}
}
// 可以看到,将伪元素设置绝对定位,并且和父元素的左上角对齐,将width 设置100%,height设置为1px,
然后进行在Y方向缩小0.5倍。
页面缓存
- 习惯将缓存分为强缓存和协商缓存两种。两者的主要区别是使用本地缓存的时候,是否需要向服务器验证本地缓存是否依旧有效。顾名思义,协商缓存,就是需要和服务器进行协商,最终确定是否使用本地缓存。
- 强缓存:浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK
- 协商缓存: 向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;
- 在做前端缓存时,我们尽可能设置长时间的强缓存,通过文件名加hash的方式来做版本更新。在代码分包的时候,应该将一些不常变的公共库独立打包出来,使其能够更持久的缓存。
性能的优化
优化的方向有两个:
- 减少页面的体积,提升网络加载;
- 优化页面渲染
减少页面体积:
- 静态资源的压缩合并(JS、CSS代码压缩合并、雪碧图)
- 静态资源缓存(资源名称加MD5戳)
- 使用CDN让资源加载更快
优化页面渲染
- CSS放前面,JS放后面
- 懒加载(图片的懒加载,下拉加载更多)
- 减少DOM的查询,对DOM查询做缓存
- 减少DOm的操作,多个操作尽量合并在一起执行
- 事件节流
- 使用SSR后端渲染,数据直接输出到HTML中,减少浏览器使用JS-模板渲染页面的HTML时间;
js拖拽功能的实现
- 首先是三件事,分别是mousedown、mousemove、mouseup,当鼠标点击按下的时候,需要一个tag标识此时已经按下,可以执行mousemove里面的具体方法。
- clientX,clientY标识的是鼠标的坐标分别标识横坐标和纵坐标,并且我们用offsetX和offsetY来表示元素的初始坐标,移动的距离应该是:鼠标移动时候的坐标减去鼠标按下去时候的坐标。
也就是说定位信息为:
鼠标移动时候的坐标 - 鼠标按下去时候的坐标 + 元素初始情况下offsetLeft - 还有一点原理性的东西,也就是拖拽的同时是绝对定位,我们改变的是绝对定位条件下的left以及top等值
- 补充:也可以通过html5的拖放(drag和drop)来实现
如何用一个setTimeout来实现setInterval
function say() {
// do something
// 可以 加点判断停止定时器
setTimeout(say, 200);
}
setTimeout(say, 200);
web worker
在HTML页面中,如果执行脚本。页面的状态是不可相应的,直到脚本执行完成后,页面才变成可相应。web worker是运行在后台的js,独立于其他脚本,不会影响页面的性能。并且通过postMessage将结果返回在主线程。这样在进行复杂操作的时候,就不会阻塞主线程了;
如何创建web worker:
- 检测浏览器对于web worker的支持性;
- 创建web worker文件(js/回传函数等);
- 创建web worker对象
http和https的区别
http传输的数据都是未加密的,也就是明文的,网景公司设置了SSl协议来对http协议传输的数据进行加密处理,简单的来说https协议是由http和ssl协议构建的可进行加密传输和身份认证的网络协议,比http协议的安全性更高。主要区别如下:
- https协议需要ca证书,费用更高;
- http是超文本传输协议,信息是明文传输的,https则是具有安全性的ssl加密传协议;
- 使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443;
- http的链接很简单,是无状态的;https协议是由ssl+http协议构建的可进行加密传输、身份认证的网络协议,比http协议更安全;
- SSl协议:安全套接字协议,靠证书来验证服务端的身份,并在本地机和服务端架起一条通道
websocket
websocket是HTML5中的协议,支持持久性连续,是一种双向协议;最大特点就是服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送消息。这是HTTP不具备的;