前端知识进阶


1. SPA

概念

SPAsingle page web application,单页Web应用,就是只有一个HTML文件的应用,所有的内容都是在这个页面中通过 javascript动态更新呈现的。
典型编写SPA的前端框架:ReactAngularVue

优点

  • 更快的用户体验:加载初始页面后,可以在用户与应用程序交互时动态地更新页面内容,而无需重新加载整个页面
  • 更接近原生应用的体验:可以通过使用类似于原生应用的路由和状态管理技术,提供更接近原生应用的用户体验,包括流畅的页面转场、数据缓存和离线访问等特性
  • 减轻服务器压力:初始加载后可以通过AJAX等技术从服务器获取数据,并在客户端动态更新页面,因此可以减少服务器的负载

缺点

  • SEO不够友好:只有一个界面,无法针对不同的内容编写不同的SEO信息
  • 首页加载速度慢:SPA单页应用通常首次加载页面时就会将相应的HTMLjavascriptCSS文件全部加载,通常可以通过采取缓存措施以及懒加载即按需加载组件的方式来优化。

首页加载优化策略

  • 代码分割(Code Splitting)
    将代码分割成多个小块,并按需加载。
  • 图片优化
    对于首屏需要加载的图片,可以进行压缩和优化,减小图片文件的大小
  • 懒加载(Lazy Loading)
    对于非首屏需要加载的组件、图片或其他资源,可以使用懒加载,待需要用到时再加载
  • CDN加速
    将静态资源缓存到离用户更近的CDN节点

2. 微前端

一种由独立交付的多个前端应用组成整体的架构风格。具体的,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的小块,而在用户看来仍然是内聚的单个产品。
将庞大的整体拆成可控的小块,并明确它们之间的依赖关系。关键优势在于:

  • 代码库更小,更内聚、可维护性更高
  • 松耦合、自治的团队可扩展性更好
  • 增量升级,独立部署,重写部分前端功能成为了可能

实现中的关键问题:

  • 多个 Bundle 如何集成?
    微前端架构中一般会有个容器应用(Container Application)将各子应用集成起来。集成方式分3类:

    • 服务端集成:如 SSR 拼装模板
    • 构建时集成:如 Code Splitting
    • 运行时集成:如通过 iframe、JS、Web Components 等方式
  • 子应用之间怎样隔离影响?

    • 样式隔离:开发规范(如BEM)、CSS 预处理(如SASS)、模块定义(如CSS Module)、用 JS 来写(CSS-in-JS)、以及shadow DOM特性
    • 作用域隔离:各种模块定义(如ES Module、AMD、Common Module、UMD)
  • 公共资源如何复用?

    • 比较推荐的模式是开源软件的管理模式:所有人都能补充公共资源,但要有人(或一个团队)负责监管,以保证质量、一致性以及正确性
  • 子应用间怎样通信?

    • 自定义事件
    • 路由
    • props传递数据等
  • 如何测试?
    每个子应用都应该有自己的全套测试方案,特殊之处在于,除单元测试、功能测试外,还要有集成测试:

    • 集成测试:保证子应用间集成的正确性,比如跨子应用的交互操作
    • 功能测试:保证页面组装的正确性
    • 单元测试:保证底层业务逻辑和渲染逻辑的正确性

微前端的框架:

  • MicroApp - 京东
  • qiankun - 阿里蚂蚁
  • 无界 - 腾讯

3. 服务端渲染 SSR

概念

服务端渲染(SSR):服务端将HTML文本组装好,并返回给浏览器,这个HTML文本被浏览器解析之后,不需要经过 JavaScript 脚本的执行,即可直接构建出希望的 DOM 树并展示到页面中,最后将这些静态标记”激活”为客户端上完全可交互的应用程序。

优点

  • 更快的首屏加载速度:因为浏览器不需要等待数据加载和渲染,因此可以提高用户的首屏体验。
  • 更好的搜索引擎优化(SEO):因为搜索引擎可以更容易地爬取完整的HTML内容,因此SSR可以更好地改善网站的SEO。
  • 更好的用户体验:因为页面的内容在服务器端渲染,因此用户可以更快地看到完整的页面,从而提高用户的使用体验。

缺点

  • 增加服务器的负载:因为服务器需要执行渲染任务,因此可能会增加服务器的负载。
  • 更复杂的环境技术:因为需要涉及到服务器端代码,因此需要更复杂的技术环境。
  • 更高的开发复杂度:因为需要在服务器端和客户端同时开发,因此可能会更高的开发复杂度。

实现

4. 客户端渲染(CSR)

概念

单页应用中使用最多的渲染方式,我们现在的项目常用使用了react、vue之类的单页应用的框架,这类框架在进行页面渲染时,会到首先对html页面进行解析并构建dom树,等js文件返回后、动态的改变 DOM 树的结构,使得页面成为希望成为的样子,从而完成页面渲染。

优点

  • 服务器响应速度快
  • 支持页面交互,适用于单页面应用

缺点

  • 首页会出现白屏
  • 页面内容由js生成,SEO不够友好

5. 静态页面生成 SSG

概念

用于静态页面的渲染方式,构建时生成完整的html页面,无需服务端请求处理,服务器响应快,非常快就可以看到展示的页面。

优点

  • 拥有良好的SEO
  • HTML已被全部生成好,首屏加载速度快

缺点

  • 适合静态页面,不支持页面交互
  • 构建过程中没有window,document等,存在库的兼容问题

6. Serverless架构

💡Serverless(无服务)基础知识

7. OAuth2.0

开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表,个人资料),而无需将用户名和密码提供给第三方应用。

  • 思路
    OAuth在“客户端”与“服务提供商”之间,设置了一个授权层(authorization layer)。“客户端”不能直接登录“服务提供商”,只能登录授权层,以此将用户与客户端区分开来。“客户端”登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。
    “客户端”登录授权层以后,“服务提供商”根据令牌的权限范围和有效期,向“客户端”开放用户储存的资料。
  • 运行流程
    1. 用户打开客户端以后,客户端要求用户给予授权。
    2. 用户同意给予客户端授权。
    3. 客户端使用上一步获得的授权,向认证服务器申请令牌。
    4. 认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
    5. 客户端使用令牌,向资源服务器申请获取资源。
    6. 资源服务器确认令牌无误,同意向客户端开放资源。
  • 授权模式
    • 授权码模式(authorization code)
    • 简化模式(implicit)
    • 密码模式(resource owner password credentials)
    • 客户端模式(client credentials)

8. 基于session的认证流程

  1. 用户使用用户名和密码登录;
  2. 服务端认证通过后创建一条 session,并生成一个token与之关联,返回响应数据的同时将token保存至客户端 cookie 中;
  3. 客户端再请求时,自动携带cookie中的 token;
  4. 服务端解析 cookie 后根据 token 去查找对应的 session 信息,如果对应 session 存在且合法,则返回正确响应数据;
  5. 服务端若未找到对应 session 信息,则返回错误提示;
  6. 客户端获取错误提示后,指引用户重新登录。

这种模式最大的问题是,没有分布式架构,无法支持横向扩展。如果使用一个服务器,该模式完全没有问题。但是,如果它是服务器群集或面向服务的跨域体系结构的话,则需要一个统一的session数据库来保存会话数据实现共享,这样负载均衡下的每个服务器才可以正确的验证用户身份。

9. JWT(JSON Web Token)

目前最流行的跨域身份验证解决方案,与session认证最大的区别就是服务器端根本不保存会话数据,即服务器变为无状态,使其更容易扩展。

用法:
客户端接收服务器返回的JWT,将其存储在CookielocalStorage中。
此后,客户端将在与服务器交互中都会带JWT。如果将它存储在Cookie中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。
当跨域时,也可以将JWT放置于POST请求的数据主体中。

认证流程:

  1. 用户使用用户名和密码登录;
  2. 服务端认证通过后,生成 token,返回客户端;
  3. 客户端保存 token,并携带 token,请求服务端资源;
  4. 服务端判断 token 是否过期,若没有过期,则解析 token 获取认证相关信息,认证通过后,将服务器资源返回给客户端;
  5. 服务端若判断 token 已过期,返回 token 过期提示;
  6. 客户端获取 token 过期提示后,指引用户重新登录。

存在的问题:

  1. JWT默认不加密,但可以加密。生成原始令牌后,可以使用改令牌再次对其进行加密。
  2. 当JWT未加密方法是,一些私密数据无法通过JWT传输。
  3. JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数。
  4. JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。
  5. JWT本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行进行身份验证。
  6. 为了减少盗用和窃取,JWT不建议使用HTTP协议来传输代码,而是使用加密的HTTPS协议进行传输。

参考文章

💡JWT全面解读、详细使用步骤

10. XSS攻击

💡如何防止XSS攻击?

11. 单点登录

概念

单点登录(SSO,Single Sign On),是在企业内部多个应用系统(如考勤系统、财务系统、人事系统等)场景下,用户只需要登录一次,即可获得访问单点登录系统中其他关联系统和应用软件的权限。
同理用户只需注销一次,就可以从多个应用系统退出登录。

工作流程

  1. 用户首次访问系统A时,需要进行登录。
  2. 系统A带着用户登录信息重定向给认证系统。
  3. 认证系统验证用户登录信息。
  4. 验证通过后,返回一个token
  5. 认证系统带着token重定向给系统A,得知用户是已登录状态。
  6. 系统A向用户返回请求的资源。
  7. 用户访问系统B时,需要进行登录。
  8. 系统B通过共享的token,得知用户是已登录状态。
  9. 系统B向用户返回请求的资源。

12. 前端权限实现

路由级权限实现

  • 系统路由初始只有通用路由,如登录,404等,登录之后从后端获取到用户的权限路由,再将这些路由动态添加到系统路由表中
  • 系统路由初始有完整的页面路由,登录之后从后端获取到用户的权限路,通过路由守卫来拦截用户权限之外的路由

按钮级权限实现

  • 使用v-if(过于粗暴,不够优雅)
  • 封装一个权限组件,用来包裹要控制的按钮。在权限组件内进行权限校验,根据校验结果来决定是否显示插槽内的按钮。
  • 自定义指令,指令内部接收权限字符,通过函数进行校验,校验未通过时,获取当前指令所在节点的父节点,来删除掉当前节点。

参考文章

💡前端权限设计实现——路由级
💡前端权限设计实现——按钮级

13. RBAC模型

概念

RBACRole-Based Access Control 的缩写,即基于角色的权限访问控制,是一种基于组织中用户的角色来调节控制对计算机或网络资源的访问的方法。
三者关系如下:
用户 <——-> 角色 <——> 权限

  • 用户和角色可以是多对一或多对多的关系
  • 某一角色拥有对应的权限

模型类型

  • RBAC0模型
  • RBAC1模型:增加了子角色,引入了继承概念,即子角色可以继承父角色的所有权限。
  • RBAC2模型:增加了对角色的一些限制:角色互斥、基数约束、先决条件角色等。
  • RBAC3模型:综合了RBAC0、RBAC1和RBAC2的所有特点,既有角色分层又有约束的一种模型。

参考文档

💡到底什么是RBAC权限模型?!

14. MVC、MVP 和 MVVM

MVC

  • Model:模型,负责保存应用数据,与后端数据进行同步
  • View:视图,负责视图展示,将 Model 中的数据可视化出来
  • Controller:控制器,负责业务逻辑,根据用户行为对 Model 数据进行修改

MVP

Model-View-Presenter

MVVM

Model-View-ViewModel

三者的关系:

  • MVC、MVP 和 MVVM 三者都是框架模式,其设计目标都是为了解决 ViewModel 的耦合问题
  • MVC 早期主要出现在后端,如 Spring MVC。前端也有应用到 MVC 的框架,如Backbone.js,同时它的优缺点都很明显:优点是分层清晰,缺点是数据流混乱,维护性较差
  • MVP 是 MVC 的一种演变,P 层作为中间层负责 Model 和 View 之间的通信,但随着应用规模的增加,P 层也会由于过于臃肿而导致难以维护
  • MVVM 可以当作是 MVP 的进化,它在前端领域中有着广泛的应用,它不但解决了 MV 耦合的问题,还同时解决了作为中间层当应用规模增加的时候需要维护二者映射关系而产生的大量繁杂代码的问题,提高了开发效率,可读性和维护性。同时,随着对 MV 层的优化(虚拟 DOM,diff 算法,模板编译),还保持了优越的性能。

15. Hybrid开发

web前端和客户端的混合开发,让App同时具备原生和 Web 的技术优势。

优点

  • 可以快速迭代更新【关键】,无需APP审核
  • 体验流畅(和Native开发的体验基本类似)
  • 减少开发和沟通成本,双端公用一套代码

    缺点

  • 性能问题
  • 兼容性问题(Android 5.0+ 和 IOS 9.0+上缺点不再明显)

应用场景

  • 微信公众号, 通过JSSDK连接Native 和 web端
  • 微信小程序,通过内置框架连接Native 和 web端

技术框架

  • Web渲染: Cordova 【前身是PhoneGap】
  • 原生渲染: React Native、Weex
  • 混合渲染: 微信小程序

参考文档

💡hybrid 开发

16. WebSocket

概念

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

特点

  • 建立在 TCP 协议之上,服务器端的实现比较容易。
  • 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
  • 数据格式比较轻量,性能开销小,通信高效。
  • 可以发送文本,也可以发送二进制数据。
  • 没有同源限制,客户端可以与任意服务器通信。
  • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

如何实现长连接的

  1. 客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
  2. 服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;
  3. 客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。

如何断线重连

利用心跳机制,即客户端定时向服务端发送一个心跳包,超过超时时间未响应则认为服务端已断线,然后客户端请求重新建立连接。

与HTTP的关系

相同点:都是一样基于TCP的,都是可靠性传输协议。都是应用层协议。
不同点:WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息,而HTTP是单向的;
联系:WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。

应用场景

  • 即时通信
  • 多玩家游戏
  • 在线协同编辑/编辑
  • 实时数据流的拉取与推送
  • 体育/游戏实况
  • 实时地图位置

文章作者: Snail-Lu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Snail-Lu !
  目录