前端小知识

cookie、sessionStorage、localStorage区别

  • 关键:数据存储位置、生命周期、存储大小、写入方式、数据共享、发送请求时是否携带、应用场景。
  • 解析:cookie、sessionStorage、localStorage都是浏览器本地的存储,都存储在浏览器本地。
    1. cookie是由服务端写入的,而sessionStorage、localStorage由前端写入;
    2. cookie的生命周期由服务器端在写入的时候设定,localStorage写入(setItem)即一直存在,除非手动清除(removeItem | clear),sessionStorage是页面关闭的时候自动清除;
    3. cooki存储空间大概4KB,sessionStorage、localStorage存储空间大概5M;
    4. cookie、sessionStorage、localStorage数据共享需遵循同源原则,sessionStorage还限制必须同页面;
    5. 前端发送请求的时候会自动携带cookie中数据,后两者不会;
    6. cookie用于存储登录验证信息sessionId或者token,localStorage存储不易变动的数据,减轻服务器压力。

JavaScript数据类型?区别

  • 关键:Number、String、Boolean、BigInt、Symbol、Null、undefined、Object。
  • 解析:数据类型一般分为两类
    1. 基础数据类型(Number、String、Boolean、BigInt、Symbol、Null、undefined);
    2. 复杂数据类型~引用数据类型(object),普通对象,数组,正则表达式,日期,Math数学函数均属于object。
  • 区别:存储方式不同,基本数据类型直接存储在栈中的数据段中,占据空间小,属于被频繁使用的数据,引用数据类型存储在堆内存中,占据空间大,引用数据类型在栈中存储了指针,指针指向堆中该实体的起始地址,属于一种引用。
  • 注释:symbol->es6新增的数据类型,没有重复的数据,可以用作Object的key。。。。。。(需要新增)
let key = Symbol('key');
  • 注解:BigInt->es6新增的数据类型,特点:数据涵盖的范围大,能够解决超出数据类型报错的问题。(不能与Number混合操作)
console.log(9007199254740999n) //9007199254740999
var bi = BigInt("9007199254740999");
console.log(bi); //9007199254740999
BigInt("520"); //520n
BigInt(520); //520n

对闭包的理解

  • 关键:变量背包、作用域链、局部变量不销毁、函数外访问函数的内部变量、内存泄漏、形成块级作用域、柯里化、构造函数中定义特权方法。
  • 解析:函数的内部返回函数,内部函数可以访问外面函数的内部遍历,形成了内部函数的变量背包,外面函数执行结束后,变量背包不会被销毁,而且变量背包在外部函数的里面,只能通过内部函数进行访问。
    1. 原理->作用域链,当前作用域访问上级作用域的变量.
    2. 解决问题->让函数作用域中的变量在函数执行结束后不被销毁,同时函数外部可以访问函数内部的局部变量。(累加函数,执行一次将数据进行累加)
    3. 存在问题->变量不会被销毁,存在内存泄漏的风险,导致内存溢出。

Promise

  • 关键:pending、rejected、resolved、微任务、then、catch、Promise.reject()、Promise.all()、Promise.any()、Promise.race()。
  • 解析:Promise是异步微任务,解决了异步多层嵌套回调的问题,是es6提供的一个构造函数,可以使用catch捕获失败,then与catch最终返回的也是一个Promise,因此可以链式调用。
    1. 特点->对象的状态不受外界影响-pending(执行中)、resolved(成功)、rejected(拒绝),前者为初始状态,后二为结束状态。
    2. 状态一旦改变,就不再会发生变化,pending->resolved | rejected;resolved方法的参数是then中回调函数的参数,reject方法的参数是catch中参数。
    3. all - 返回新的Promise对象,该对象在参数对象里所有的Promise对象都成功才触发成功,存在失败即触发失败。
    4. any - 接收Promise对象的集合,其中一个成功,即触发成功,并返回成功的Promise值。
    5. race 参数中任意一个Promise成功或者失败,父级Promise会使用子级Promise的返回值(成功|失败)作为参数调用父级Promise绑定相应的句柄,并返回该Promise对象。

跨域?如何解决

  • 关键:同源限制、协议、域名、端口、cors、node中间件、jsonp、postmessage
  • 解析:跨域,页面中的某个请求接口的地址与页面的地址协议、域名、端口存在其中一项不同(即跨域),原因:浏览器保证网页安全,出现的同源协议策略
    1. 最常见的解决方法,后端允许跨域实现;
    2. node中间件、Nginx反向代理-跨域限制浏览器不能跨域访问服务器,node中间件与Nginx反向代理,让请求发给代理服务器,静态页面和代理服务器是同源的,代理服务器统一向后端发送请求,服务器与服务器之间不存在同源限制;
    3. jsonp-利用script标签可以跨域请求资源,将回调函数作为参数拼接到url中,后端接收到请求,调用该回调函数,并将数据作为参数返回到函数中,注意设置响应头返回文档类型,应设置成JavaScript。
    4. postmessage-H5新增API,通过发送与接收API实现跨域通信。
<script>
function jsonpFunc(data){
	// data为后端返回数据
}
</script>
<script src="https://www.xzp.cn/main/?callback=jsonpFunc"></script>
<script>
	$.ajax({
		type:"get",
		url:"https://www.xzp.cn/main/?callback=jsonpFunc",
		dataType:"jsonp",
		success:function(res){
		}
	})
</script>

JavaScript判断变量类型

  • 关键:typeof、instanceof、Object.prototype.toString.call()、constructor
  • 解析
    1. typeof-判断基本数据类型(Number、String、Boolean、undefined、function),引用数据类型除方法返回function外,其余返回Object;
    2. instanceof-区分引用数据类型,检测数据的原型链;
    3. constructor-检测引用数据类型,获取数据的构造函数判断与某个类是否相同;
    4. Object.prototype.toString.call()-适用于检测任何类型的数据,Object.prototype.toString.call(数据)
var n = 1, s = 'str', b = false, u = undefine, nl = null, o = {}, a = [], f = function(){};
typeof n === 'Number'
u instanceof  undefine
Object.prototype.toString.call(a)

性能优化

  • 关键:图片| 文件压缩、雪碧图/精灵图、节流防抖、http缓存、本地缓存、Vue的keep-alive缓存、ssr服务器端渲染、懒加载、对dom查询进行缓存、将dom操作合并。
  • 解析: 文件加载更快
    1. 让传输的数据包更小(压缩文件/图片),图片|文件压缩;
    2. 减少请求次数:雪碧图/精灵图、节流防抖;
    3. 减少渲染测试:缓存(http缓存、本地缓存、Vue的keep-alive缓存)。
  • 文件渲染更快
    1. 提前渲染;
    2. ssr服务器渲染,避免渲染阻塞;
    3. css文件放在页面头部,js放在页面底部,确保页面渲染正确后,再载入交互逻辑;
    4. 懒加载,减少渲染次数:对dom查询缓存,将dom操作合并、减少重排的。

重排与重绘

  • 关键:重排必然触发重绘,重绘不一定会重排
  • 解析:重排
    1. 添加或删除可见的dom元素;
    2. 元素位置变化;
    3. 元素尺寸变化;
    4. 内容变化(内容增加|减少导致高度|宽度变化);
    5. 页面渲染器初始化;
    6. 浏览器窗口尺寸改变。
  • 重绘 - 元素外观发生改变,没改变布局(例如背景、字体颜色改变)。
  • 减少重排
    1. 样式集中改变;
    2. 脱离文档流(absolute、fixed);
    3. GPU加速(获取dom分割成多层,将每个层栅格化并独立绘制进位图,位图上传至GPU,复合多个层生成最终屏幕图像开启GPU加速的元素被独立出来,不再影响其他dom布局)

实时通信

  • 关键:轮询、长轮询、iframe流、websocket、sse。
  • 解析
    1. 轮询 - 客户端与服务器,间隔一定时间访问一次,缺点:消耗流量,消耗CPU利用率,轮询间隔时间过长:不能及时接收更新,间隔过短:增加负担;
    2. 长轮询- 轮询的改进版,客户端发送请求给服务器后,若没有更新,则等待(pending),存在更新,则返回给客户端。优点:保证较好的时效性,缺点:保持连接会消耗资源,服务器无返回,程序超时。
    3. iframe流- 页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建长连接,服务器向iframe传输数据(html内部负责插入信息JavaScript)。优点:时效性好,兼容性好。缺点:维护长连接增加开销;IE、chrome、Firefox会显示加载未完成,图标不停旋转。
    4. websocket websocket连接建立后,数据以帧序的形式传输,客户端断开websocket连接之前,不需要再次发起连接。缺点:浏览器支持程度不一致,不支持断开重连。
    5. sse(server-sent event) 建立浏览器与服务器之间的通信渠道,服务器向浏览器推送消息,sse为单向通道,服务器->浏览器。优点:sse使用http协议,兼容性好,支持断线重连。

箭头函数

  • 关键:没有this、this从外部获取、没有arguments、没有原型、没有super
  • 解析:继承执行上下文的this,箭头函数无this关键字无法作为构造函数。

事件循环event loop、微任务、宏任务

  • 关键:任务挂起、同步任务执行结束任务队列中的异步任务、执行script标签内部代码、setTimeout/setInterval、ajax请求、postMessage、setImmediate、I/O(node)Promise、MutonObserver、Object.observer、process.nextTick(node.js) - 每个宏任务都包含一个微任务队列
  • 解析
    1. 同步任务-立即执行的任务,于主线程排队执行,按照顺序执行,前一个任务执行结束->后一个任务开始执行。
    2. 异步任务-异步执行的任务,不进入主线程,而是在异步任务返回结果后,将注册的回调函数放入执行任务队列中等的主线程空闲的时候读取执行。
    3. 主线程不断从任务队列读取时间,这个过程是循环不断的,这种机制就叫event loop(事件循环)
  • 宏任务:script标签、setTimeout、setInterval、setImmediate、I/O操作
  • 微任务:promise.then/catch/finally(回调)、、mutationObserver回调

CSRF攻击

  • 关键:CSRF跨站请求伪造、盗用用户身份发起请求
  • 解析:跨站点请求伪造与xss攻击一样,存在巨大危害性(攻击者盗用用户身份,已用户身份发起恶意请求,但服务器判断该请求为合理请求。
    1. 原理-用户打开浏览器,访问目标网站A,输入用户名与密码请求登录,用户信息认证通过,网站A产生cookie信息返回给浏览器,用户A可正常发送请求到网站A,用户未退出网站A,打开网站B,网站B返回攻击代码,并发送请求访问已返回cookie的网站A,攻击代码在用户不知情情况下通过用户权限操作了cookie并向网站A发起了合法请求。
    2. 预防-验证码,在表单中添加一个随机数字或字母验证,强制要求用户和应用进行直接的交互。
    3. 预防-http请求referer字段,检查是不是争取域名访问过滤的,它记录了http请求的来源地址。
    4. 预防-token验证,http请求头中添加token字段,并且在服务器端建立一个拦截器验证token,若token错误,则拒绝该请求。
    5. 验证referer优点-实施简单,普通网站开发不需要担心CSRF漏洞, but 不同浏览器可能在referer实现上存在自身漏洞,会被修改;因此使用token验证更安全。

defer与async区别

  • 关键:载入js文档与渲染文档可同时进行、js代码立即执行、js代码不立即执行、js代码立即执行、渲染引擎与js引擎互斥
  • 解析:浏览器立即加载js文件并执行指定脚本,立即是指渲染该script标签之下的文档元素之前,也就是说不等待后续加入的文档元素,读到即加载并执行。
  • defer:加载后续文档元素与script的加载并行(异步),但script脚本需要在所有元素解析完成才执行,即DOMcontentLoaded事件触发之前完成。
  • async:加载与渲染后续文档元素并行(异步),script加载完成后,暂停渲染后续文档,立即执行script脚本。
<script async src="xzp.js"></script>
<script defer src="xzp.js"></script>

浏览器渲染页面

  • 关键:dom树、stylesheet、布局树、分层、光栅化、合成
  • 解析:浏览器载入HTML,将HTML转为dom树,将css样式转为stylesheet,根据dom树与stylesheet创建布局树,对布局树进行分层处理,为每个图层生成绘制列表,将图层分成图块,光栅化将图块转为位图,最后绘制生成页面。
  • 附加
    1. 分层目的,页面单个图层渲染,不会触发整个页面渲染,尤其动画的时候,将动画放在独立的图层,可提高渲染效率。(css属性transform、z-index,浏览器自动优化生成图层)
    2. 光栅目的:如果页面很长,可视区很小,避免渲染非可视区的样式造成资源浪费,因此将每个图层划分为多个小格子,只渲染可视区附近区域。

浏览器输入URL

  • 关键:DNS解析、tcp握手、http缓冲、重定向、服务器状态码、渲染引擎与js引擎互斥、渲染过程、浏览器进程、网络进程、渲染进程
  • 注解
    1. 查看浏览器缓存-系统缓存-路由器缓存,若缓存中存在该页面,直接显示页面内容。
    2. 域名解析(DNS解析),解析获取相应的IP地址。
    3. 浏览器向服务器发起TCP连接,与服务器TCP三次握手。
    4. TCP连接建立成功,浏览器向服务器发送http请求,获取数据。
    5. 服务器处理接收到的请求,将数据返回至浏览器。
    6. 浏览器接收http响应。
    7. 浏览器读取返回数据,浏览器渲染,解析html源码。
    8. 生成DOM树,解析css样式,js交互。

可过期的localStorage

  • 关键:懒惰性删除、定时删除
  • 注解:localStorage可保存长久保存浏览器数据,保存数据没有过期时间,需要手动删除或localStorage.removeItem(key)
    1. 惰性删除:键值过期不会马上删除,需要等到使用时,检查是否过期,若过期则删除该键值对应的缓存。需要存储过期时间
    2. 定时删除:间隔一段时间,通过限制删除操作执行次数与频率,减少删除操作对cpu的占用。定时删除有效减少惰性删除带来对localStorage空间的浪费。
    3. 定时删除逻辑:间隔一段时间执行一次 1、随机测试n个localStorage的key;2、删除已经过期的key;3、若删除的key超过五个(说明过期的key很多)重复步骤1,直至重复500次(强行跳出循环)

token存在cookie中

  • 关键:可以存在cookie中、不设置cookie有效期、重新登录重写cookie覆盖原本的cookie
  • 注解:token - 1、用户使用用户名与密码请求登录;2、服务端收到请求,验证用户名与密码;3验证成功,服务器签发token,并返回给用户的;4、用户接收token将其存储起来(cookie或localStorage);5、用户发送请求均将token放在http的header里;6、服务器收到请求,验证token,判断token是否正确或过期,若验证成功则返回对应的数据。
    1. token:判断用户是否登录,内部信息:uid(用户唯一标识),time(当前时间戳),sign(签名)
    2. token存储于cookie中,不设置cookie过期时间,若token失效,后端返回token失效状态,重新登录,重新设置cookie中token。

MVC与MVVM区别

  • 关键:MVC->model(模型)、view(视图)、controller(控制器);MVVM->model(模型)、view(视图)、viewModel
  • 注解
    1. model,应用程序用于处理应用程序数据逻辑部分,模型对象负责数据库中数据存取;
    2. view,处理数据显示部分,视图是依据模型数据穿件的;
    3. controller,处理用户交互部分,通过控制器操作节点;
    4. viewModel,连接view与model桥梁,将view与model同步,当model数据改变,自动改变view显示。
  • 附加
    1. mvvm不直接操作节点,而是数据来显示视图层。
    2. mvvm解决mvc中大量dom操作使页面渲染性能降低,加载速度变慢。
    3. mvvm不可以取代mvc,viewModel存在目的在于抽离controller中展示的业务逻辑,其它视图操作业务仍然需要controller实现。

HTML5新特性

1. 新增选择器 document.querySelector、document.querySelectAll
2. 拖拽释放(Drag 与 drop)API
3. 媒体播放器 video 与 audio
4. 本地存储localStorage与sessionStorage
5. 离线应用 manifest
6. 桌面通知 Notifications
7. 语意化标签 article、footer、header、nav、section
8. 增强表单控件 calender、date、time、email、url、search
9. 地理位置 Geolocation
10. 多任务 webworker
11. 全双工通信协议 wbsocket
12. 历史管理history
13. 跨域资源共享(CORS) Access-Control-Allow-Origin
14. 页面可见性改变事件visibilityChange
15. 跨窗口通信postMessage
16. form data对象
17. 绘画canvas

伪类与伪元素

  • 关键:伪类->已存在元素处于某种状态(根据用户行为变化);伪元素->创建一些不在dom树的元素。
  • 注解:两者都可以添加对应的样式以达到需要的效果。

HTML5语义化

  • 关键:HTML5新增语义化标签,更清晰表单文档结构。
  • 注解:优点1、易于用户阅读,样式丢失时,能让页面呈现清晰的结构;2、利于SEO,搜索引擎根据标签确定上下文和各个关键词的权重;3、方便屏幕阅读器解析;4、便于开发和维护,语义化更具可读性,代码更好维护。

iframe优点与缺点

  • 优点
    1. iframe可以原封不动把嵌入的页面展现出来
    2. 多个网页引用iframe,只需修改iframe的内容,则可实现调用的每个页面都更改,更便捷。
    3. 网页统一风格,头部与版本都一样,则可以写成单个页面,用iframe来嵌套,增加代码的可重用。
    4. 若遇到加入缓慢的第三方内容(图标、广告),可使用iframe解决。
  • 缺点
    1. iframe会阻塞主页面的onload事件。
    2. iframe和主页面共享连接池,而浏览器对相同域的连接有限制,影响页面并行加载,会产生很多页面,不易于管理。
    3. iframe框架结构可能会出现上下、左右滚动条,分散访问者注意力,用户体验差。
    4. 代码复杂,无法被搜索引擎查询到,不利于搜索引擎优化(SEO)。
    5. 移动设备无法完全显示框架,设备兼容性差。
    6. iframe框架页面会增加服务器http请求,对于大型网站不可取。

href与src区别

  • 关键:src->替换当前元素;href:当前文档与引用资源之间确立联系。
  • src
    1. src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中标签所在位置。
    2. 请求src资源会将其指向的资源下载并应用到文档(js脚本、img图片与iframe等)。
    3. 解析到该元素,将会暂停其它资源的下载与处理,直到将该资源加载、编译、执行完毕(图片、iframe元素也如此)。
  • href
    1. href是hypertext reference所示,指向网络资源所在的位置,建立和当前元素(锚点)或当前文档(链接)直接的连接。
    2. 浏览器解析到该元素,并不会停止对当前文档的处理。
<script src="index.js"></script>
<link href="index.css" rel="stylesheet">

箭头函数

  • 特性
    1. 箭头函数不会创建自身的域(this)。
    2. 箭头函数的this根据上下文而定,且无法改变。
    3. call()/apply()/bind()无法改变箭头函数的this指向。
        let func = function(a, b, c){
            this.a = a;
            this.b = b;
            this.c = c;
        }
        let a = 1, b = 2, c = 3;
        let obj = {};
        func.call(obj, a, b, c);
        func.apply(obj, [a,b, c]);
        func.bind(obj)();
    
    1. 箭头函数不能用作构造函数。
    2. 箭头函数没有自身的arguments。
    3. 箭头函数没有原型prototype。

微任务与宏任务

  • 微任务:process、nextTick、mutation、observer、promise.then、catch、finally
  • 宏任务:I/O、setTimeout、setInterval、setImmediate、requestAnimationFrame
  • 运行机制
    1. 执行栈中执行一个宏任务。
    2. 执行过程遇到微任务,将微任务添加到微任务队列中。
    3. 当前宏任务执行完毕,立即执行微任务队列中的任务。
    4. 当前微任务队列中的任务执行完毕,检查渲染,GUI线程接管渲染。
    5. 渲染完毕,js线程接管,开启下一次事件循环,执行下一个宏任务(事件队列中取出)。

死锁

  • 解析:两个或者两个以上进程在执行过程中,由于竞争资源而造成阻塞的现象,若无外力作用,将无法继续执行。
  • 原因
    1. 竞争资源引起进程死锁
    2. 可剥夺资源与非剥夺资源
    3. 竞争非剥夺资源
    4. 竞争临时性资源
    5. 进程推进顺序不当
  • 条件
    1. 互斥条件:涉及资源是非共享的(当前时间段内资源R被进程A占用,若其它进程请求资源R,请求者需要等待,直至占用资源的进程执行完毕释放)。
    2. 不剥夺条件:不能强行剥夺进程拥有的资源(进程已获得的资源,在未使用完毕之前,不能被剥夺,知道使用完毕释放)。
    3. 请求和保持条件:进程在等待新资源时,继续占用已分配的资源。
  • 解决
    打破四个必要条件之一,即可有效预防死锁的发生。

文件上传

  • 实现方式
    1. 表单上传,form表单上传大文件,容易超时。
    2. 文件编码上传(示例:图片转为base64)。
    3. formData异步上传(let formData = new FormData(); formData.append(‘file’, file))。
    4. iframe 无刷新页面。
  • 拓展:大文件上传
    1. 拆分上传请求(切片)。
    2. 断点续传。
    3. 显示上传进度与暂停上传。
// 切片上传
let chunks, piece = 1024 * 1024 * 5;
let totalSize = file.size;
let end = piece;
for(let start = 0; start < totalSize; start++){
    let blob = file.slice(start, end);
    chunks.push(blob);
    start = end;
    end = start + piece;
}

防抖与节流

  • 防抖:事件触发n秒后执行回调,若n秒内重复触发,则重新开始计时。
function debounce(func, delay){
    let timer;
    return function(){
        let _this = this; // setTimeout 回调使用箭头函数不需要
        let args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function(){
            func.apply(_this, args);
        }, delay);
    }
}
  • 节流:每隔一段时间,执行一次函数
function throttle( func, delay){
    let timer;
    return function(){
        let _this = this;
        var args = arguments;
        if(timer)return;
        timer = setTimeout(function(){
            func.apply(_this, args);
            timer = null;
        }, delay)
    }
}
function throttle( func, delay){
    let previous = 0;
    return function(){
        let args = arguments;
        let nowTime = new Date().getTime();
        if(nowTime - previous > delay){
            func.apply(this, args);
            previous = nowTime;
        }
    }
}

判断为空对象

function isEmpty(obj){
    return (obj === null || obj === undefined || (typeof value === 'object' && Object.keys(obj).length === 0))
}

闭包

  • 埋点
function count(){
    let num = 0;
    return function(){
        return ++num;
    }
}
let luoxz = count();
let xiaozp = count();
console.log(luoxz()); // 1
console.log(luoxz()); // 2
console.log(xiaozp()); // 1
  • 事件+循环
let dom = document.querySelectorAll(".xzp");
for(let i = 0; i < dom.length; i++){
    (function(x){
        dom[x].onclick = function(){
            console.log(x);
        }
    })(i)
}

移动点击(300ms延迟、穿透)

  • 移动端存在双击缩放操作,浏览器click等待300ms,判断操作是否为双击。
  • 解决方案:
    1. 禁用缩放:user-scalable=no
    2. 更改默认的视口宽度
    3. css touch-action
  • 点击穿透问题,click事件300ms延迟问题,可能存在某些情况触发多次事件。
    1. 仅使用touch
    2. 仅使用click

响应式开发

  • 兼容不同大小的设备,如pc端、移动端(平板、竖屏、横屏)的显示风格。

前端性能优化

  • 加载优化:减少http请求、缓存资源、压缩代码、无阻塞、首屏加载、按需加载、预加载、压缩图像、减少cookie、避免重定向、异步加载第三方资源。
  • 执行优化:css头部,js尾部并异步(deffer)、避免img、iframe等的src为空、尽量避免重置图像大小、图像尽量避免使用dataUrl。
  • 渲染优化:设置viewport、减少dom节点、优化动画、优化高频事件、GPU加速。
  • 样式优化:避免在html写在style、避免css表达式、移除css空规则、争取使用display、不滥用float。
  • 脚本优化:减少重绘和回流、缓存dom选择与计算、缓存length长度、尽量使用事件代理、尽量使用id选择器、touch事件优化。

url加密解密

  • 加密:escape、encodeURL、encodeURLComponent;解密:unescape、decodeURL、decodeURLComponent。
  • escape出ASCII字母、数字和特定的符合,对传进来的字符串全部进行转码(url加密不建议使用)。
  • encodeURL编码整个url中合法字符不会被转码;encodeURLComponent编码单个URLComponent最常用,可以将参数中的中文、特殊字符进行转码,而不会影响URL。

同源策略及其限制内容

  • 浏览器最核心也最基本的安全功能,如果缺少同源策略,浏览器容易受到XSS、CSRF等攻击。同源指:协议+域名+端口相同。
  • 同源策略限制:cookie、localStorage、indexDB等存储性内容;dom节点; Ajax请求发送后,结果被浏览器拦截。
  • 跨域本质:请求发送出去,服务器接收并正常返回请求,浏览器拦截。

跨域方法

  • jsonp:通过script标签向服务器发送get请求,服务器返回text/plain格式的文件,文件内容是对方法的调用。
  • 优点:简单、兼容性好;缺点:仅支持get请求、容易受到XSS攻击。
// 实现
function jsonp({url, params}){
    return new Promise((resolve, reject)=>{
        let arrs = [];
        let callback = "callback" + parseInt(Math.random() * 10000)
        window[callback] = function(data){
            resolve(data);
            document.body.removeChild(script)
        }
        for(let key in params){
            arrs.push(`${key}=${params[key]}`)
        }
        let script = document.createElement("script");
        script.src = `${url}?${arrs.join("&")}&callback=${callback}`;
        document.body.appendChild(script);
    })
}
// 调用
jsonp({url:"www.baidu.com", params:{name:"xzp", password:"123"}}).then(res=>{
    console.log(res)
})
  • CORS->浏览器自动进行CORS通信,实现CORS通信的关键是后端,需要后端设置Access-Control-Allow-Origin开启。
  • postMessage->XMLHttpRequestLevel2的API
    1. 页面和其打开的新窗口的数据传递。
    2. 多窗口直接消息传递。
    3. 页面与嵌套的iframe消息传递。
    4. 跨域数据传递
// 发送消息
window.opener.postMessage(data);
// 监听消息 / 取消监听 (todo为方法)
window.addEventListener("message", todo);
window.removeEventListener("message", todo)
  • websocket 持久化协议,浏览器与服务器的全双工通信(均基于tcp协议),建立连接后,websocket的server与client均可以主动向对方发送或接收数据。
// socket.js
let socket = new WebSocket("ws://localhost:3000");
// 发送消息至服务器
socket.onopen = function(){
    socket.send("我是猪皮");
}
// 接收服务器消息
socket.onmessage = function(e){
    console.log(e.data)
}
// server.js
let express = require("express");
let app = express();
let WebSocket = require("ws");
let wss = new WebSocket.Server({port:3000});
wss.on("connection", function(ws){
    ws.on("message", function(data){
        console.log("呵呵");
        ws.send("我是狗皮");
    })
})
  • node中间件代理:同源策略是浏览器需要遵循的标准,而服务器向服务器请求无需遵循。
    1. 接收客户端请求
    2. 将请求转发给服务器
    3. 接收服务器响应数据
    4. 将响应数据转发给客户端
  • nginx反向代理:原理类似于node中间件代理,需要搭建中转nginx服务器,用于转发请求。
    1. 使用nginx反向代理实现跨越,是最简单的跨越方式。
    2. 需要修改nginx配置即可解决跨域问题,支持所有浏览器,支持session,需要修改任何代码,并不会影响服务器性能。
  • window.name + iframe
    1. window.name属性值在不同的页面(不同域名)加载后依旧存在,并且支持2MB(大小)。
    2. 通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name外域传递到本地域。

前后端实时通信

  • websocket 优点:浏览器与服务器只需一次握手,即可实现双向数据传输;缺点:1、兼容问题,不兼容低版本浏览器,2、不支持断线重连,需要手写心跳连接的逻辑,3、通信机制相对复杂。
  • server-sent-event 优点:简单易用,内置断线重连功能;缺点:单向的,支持服务器->客户端数据传送,兼容性低。
  • ajax轮询 优点:兼容性好;缺点:浪费资源。
  • flash socket 优点:兼容性好;缺点:浏览器开启flash需要客户确认,加载时间长,客户体验差,大多数移动端不支持。

常见http status

  • 1**:指定客户端应响应的某些动作,代表请求已接收,需要继续处理。
  • 2**:代表请求已成功被服务器接收、理解、并接受。
  • 3**:需要客户端采取进一步操作才能完成请求,用来重定向,后续的请求地址(重定向目标)于本次响应的location域中指明。
  • 4**:请求错误,客户端可能发生错误,妨碍服务器处理。
  • 5**:服务器处理请求的过程中存在错误或异常状态,也可能是服务器意识到当前的软硬件资源无法完成对请求的处理。

登录方式

  • cookie+session登录

    前端使用输入用户名+密码上传,服务器验证密码 无误,创建sessionId,并保存。
    用户获取得到sessionId每次请求自动带上写入cookie的sessionId。
    缺点:服务器需要存放大量的sessionId,若为集群,需要同步登录状态,增加了维护成本。
    
  • token登录

    服务端生成的一串字符串,以作为客户端请求的令牌,第一次登录,服务器生成token并返回给客户端。客户端后续访问,需带上token即可完成身份验证。
    缺点:token下发后在生效时间内一直有效,服务器收回token权限困难。
    
  • sso单点登录

    公司内部搭建公共的认证中心,公司所有的产品登录都可以在认证中心里完成。单个产品在认证中心登录后,访问其他的产品,可以不用再次登录。
    
  • oauth第三方登录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值