【八股篇】前端面试,看这一个系列就够了!(二)

936 阅读1小时+

前言

本系列文章根据作者多年一线大厂面试经验精选了一些高频面试题,目的是让有一定工作经验的读者用较短的时间消化复习完本文后,能够应对绝大多数大厂前端面试场景。

技术问题

输入URL到页面显示的过程

juejin.cn/post/692867…

输入URL到页面显示的过程大致可以分为以下几个步骤:

  1. 用户输入 URL: 用户在浏览器地址栏输入或粘贴一个URL(统一资源定位符)。
  2. DNS 解析: 浏览器首先查找本地DNS缓存,如果找不到,则向ISP的DNS服务器发送DNS查询请求,获取该URL对应网站的IP地址。
  3. TCP 连接: 得到IP地址后,浏览器开始与服务器建立TCP连接(通常使用HTTP协议,HTTPS则先进行TLS/SSL握手加密连接)。
  4. 发送HTTP请求: 浏览器构建HTTP请求报文,包含请求方法(如GET、POST等)、请求头(如User-Agent、Accept等)和可能的请求体,然后将这个请求报文通过已建立的TCP连接发送给服务器。
  5. 服务器处理请求: 服务器接收到请求后,解析请求报文,根据请求路径找到对应的资源,进行相应的处理(如调用CGI脚本、运行服务器端代码、读取静态文件等)。
  6. 生成响应: 服务器生成HTTP响应报文,包括状态码(如200 OK)、响应头(如Content-Type、Set-Cookie等)和响应体(即要返回给浏览器的内容,通常是HTML、CSS、JavaScript等文件)。
  7. 浏览器接收响应: 浏览器接收到来自服务器的响应报文,开始解析响应头和响应体。
  8. 解析HTML: 浏览器开始解析响应体中的HTML文档,构建DOM树(Document Object Model)。
  9. 下载资源: 浏览器根据HTML文档中的链接下载其他相关资源,如CSS样式表、JavaScript文件、图片、字体等。
  10. 渲染页面: 当HTML文档下载完毕并构建DOM树后,浏览器根据CSSOM(CSS Object Model)计算样式布局,绘制页面(Layout与Paint过程)。
  11. 执行JavaScript: 如果页面包含JavaScript代码,浏览器会执行这些代码,可能会修改DOM结构或CSS样式,导致重新布局和绘制。
  12. 页面显示: 经过上述步骤,浏览器完成了所有资源的下载、解析和渲染,最终将整个页面内容呈现给用户。

以上就是从输入URL到页面显示的大致过程,实际过程中还包括很多如缓存处理、重定向、并发请求优化等细节。

扫码登陆的原理

juejin.cn/post/692421…

扫码登录是一种便捷的身份验证和授权方式,它主要用于不同平台间(例如网页端与移动端)的无缝切换登录,无需用户手动输入账号密码。下面是扫码登录的基本流程和原理概述:

  1. 生成二维码

    • 用户在网页端点击“扫码登录”按钮后,网页服务器生成一个全局唯一的标识符(如UUID)。
    • 这个标识符通常会被编码成一个二维码,网页端将此二维码展示给用户。
  2. 二维码关联用户身份

    • 生成二维码的同时,服务器会将此UUID作为一个临时密钥存储在服务器端(如Redis缓存中),并设定一个较短的有效期。
    • 存储的内容一般包括UUID以及可能的其他安全信息,如一个一次性使用的token。
  3. 移动端扫码

    • 用户使用手机App扫描网页上的二维码,App读取到二维码中的UUID信息。
    • App内部已经保存了用户的登录态信息,比如用户的Token或者其他身份认证凭据。
  4. 验证请求

    • 手机App获取到UUID后,将该标识符与用户的认证信息(如token)打包成一个安全的请求,发送至移动端服务器。
    • 移动端服务器收到请求后,验证用户身份合法性,并与网页端服务器通信(通常是通过API调用)。
  5. 授权确认

    • 如果验证通过,移动端服务器通知网页端服务器这个UUID所代表的用户已经完成身份验证。
    • 在某些情况下,App还会要求用户在手机上确认是否授权登录网页端应用,以增加安全性。
  6. 网页端响应

    • 网页端服务器接收到授权成功的信号后,清除之前存储的UUID,同时根据移动端提供的信息识别用户,并建立相应的登录态。
    • 网页端接着跳转至登录成功的界面,用户无感知地完成了登录过程。

总结来说,扫码登录通过二维码作为中间媒介传递用户身份验证信息,利用已登录的移动端应用作为信任来源,实现了跨平台的快速登录体验,同时也保证了较高的安全性和便利性。

单点登录(SSO)

juejin.cn/post/704432…

单点登录(Single Sign-On,简称SSO)是一种网络安全机制,允许用户在一个系统中登录后,无需再在其他相关的系统中分别进行登录就能访问这些系统中的资源。以下是单点登录的一般原理概述:

  1. 用户访问系统

    • 用户首先尝试访问单点登录环境中的某个应用系统(称为CAS Client或其他类型的应用客户端)。
  2. 重定向到认证中心

    • 应用系统检测到用户未登录,会重定向用户到统一的认证中心(CAS Server或其他SSO服务)。
  3. 用户认证

    • 用户在认证中心提交用户名和密码等凭证进行认证。
    • 认证中心验证用户凭证,如果有效,则认为用户已通过身份验证。
  4. 发放凭证

    • 认证成功后,认证中心会生成一个唯一的认证凭证,如票据(Ticket)或者令牌(Token)。
    • 认证中心通过某种方式(如设置Cookie或HTTP重定向携带Ticket/Token)将凭证传递回用户浏览器。
  5. 客户端验证

    • 用户浏览器在获得凭证后,再次访问原始应用系统时会携带这个凭证。
    • 应用系统(CAS Client)验证从认证中心接收到的凭证的有效性。
  6. 建立会话

    • 当应用系统验证凭证有效后,会在本地为用户建立会话,赋予其访问权限,此时用户已经登录到了该应用系统,无需再次输入用户名和密码。
  7. 跨系统访问

    • 当用户尝试访问同一单点登录环境中的其他应用系统时,同样的验证流程会简化执行,因为用户已经处于有效的认证状态。
    • 浏览器会自动携带凭证去访问新的系统,新系统也能够验证这个凭证并通过认证中心确认用户身份,从而让用户无缝地登录新系统。

不同的单点登录方案可能会采用不同的技术和协议来实现上述流程,如SAML(Security Assertion Markup Language)、JWT(JSON Web Tokens)、OAuth、OpenID Connect等。其中CAS(Central Authentication Service)是专门针对Web应用的一种较为成熟的单点登录框架,其工作流程正如上述原理所述。

OAuth2.0

juejin.cn/post/727633…

OAuth 2.0 是一个授权框架,允许第三方应用在用户授权下访问用户的某些资源,而无需获取用户的账号密码。OAuth 2.0 主要用于授权(Authorization),它允许用户给予第三方应用有限的、特定的权限,而不用担心泄露自己的敏感信息。

OAuth 2.0 工作流程简述:

  1. 授权请求

    • 第三方应用(Client)引导用户到资源所有者的授权服务器(Authorization Server)。
    • 用户在授权服务器上登录并确认愿意给予第三方应用某些权限(Scope)。
  2. 授权码(Authorization Code Grant)

    • 用户授权后,授权服务器会给第三方应用返回一个授权码(code)。
    • 第三方应用使用这个授权码和预先注册的客户端密钥(Client ID和Client Secret),向授权服务器请求访问令牌(Access Token)。
  3. 获取访问令牌

    • 第三方应用向授权服务器提交授权码和必要的凭证,换取访问令牌。
    • 授权服务器验证信息无误后,返回访问令牌和(可选的)刷新令牌(Refresh Token)。
  4. 访问资源

    • 第三方应用持有访问令牌后,每当需要访问用户资源时,在请求头中附带访问令牌,向资源服务器(Resource Server)请求数据。
    • 资源服务器验证访问令牌的有效性,若通过,则允许访问相应的资源。
  5. 令牌续期(适用于拥有刷新令牌的情况):

    • 访问令牌有过期时间,当过期时,第三方应用可以用刷新令牌去获取新的访问令牌,从而延长对用户资源的访问权限。

OAuth 2.0 通过这种方式保证了用户数据的安全性,同时让第三方应用能够在用户的授权下合法访问资源,而无需知道用户的登录凭证。此外,OAuth 2.0 还支持其他的授权类型,如隐式授权(Implicit)、客户端凭据授权(Client Credentials)和资源拥有者密码凭据授权(Resource Owner Password Credentials)等。

服务端渲染

juejin.cn/post/684490… juejin.cn/post/684490…

服务端渲染(Server-Side Rendering, SSR)是一种Web应用程序的渲染方式,尤其在使用诸如React、Vue、Angular等现代前端框架构建的SPA(Single Page Application)中常见。服务端渲染的基本原理是:

  1. 用户发起请求

    • 当用户通过浏览器访问一个支持服务端渲染的Web应用时,浏览器向服务器发送HTTP请求。
  2. 服务端响应

    • 服务器接收到请求后,不像传统的静态HTML页面那样直接返回已渲染好的HTML,而是运行Node.js服务或其他后端服务中的JavaScript代码,执行前端框架(如React)的渲染逻辑。
  3. 执行渲染

    • 服务器会执行相应的React组件树(或Vue、Angular等框架的组件),并将组件的状态和props注入,生成完整的HTML页面结构。
  4. 生成HTML响应

    • 服务器端渲染完成后,生成包含所有必需HTML、CSS(内联或链接样式表)和JavaScript(通常是打包好的bundle文件)的完整响应体,发送给客户端浏览器。
  5. 浏览器渲染

    • 浏览器接收到服务器返回的HTML响应后,迅速解析并渲染出页面,用户可以看到初步呈现的页面内容,搜索引擎爬虫也能抓取到有意义的HTML内容,这对SEO(搜索引擎优化)非常有利。
  6. 客户端接管

    • 页面在浏览器中加载完毕后,前端框架在客户端开始运行,通常会进行所谓的“hydration”(水合)过程,即将服务器生成的HTML标记转换为可交互的、由JavaScript驱动的组件树。
    • 此后,客户端接管页面交互和路由跳转,提供流畅的SPA体验。

服务端渲染的优点在于初次加载时能更快地呈现页面内容、利于SEO优化,同时也可以在弱网环境下改善用户体验。但同时,它也增加了服务器端的计算负担,并且在某些情况下,可能会增加首屏加载时的总体字节大小。

浏览器页面渲染机制

juejin.cn/post/684490…

浏览器页面渲染机制是一个复杂的过程,主要包括以下几个关键步骤:

  1. HTML解析

    • 浏览器首先接收到服务器返回的HTML文档,通过HTML解析器将其解析为DOM(Document Object Model)树。DOM树是一种结构化的表示,反映了HTML文档元素及其层级关系。
  2. CSS解析

    • 同时,浏览器还会解析CSS(Cascading Style Sheets)资源,生成CSSOM(CSS Object Model)树。CSSOM描述了各元素应该如何显示,包括颜色、大小、布局等样式信息。
  3. DOM与CSSOM合并

    • DOM树和CSSOM树合并成Render Tree(渲染树),渲染树只包含可见元素以及与之相关的样式信息。在这个过程中,那些被CSS隐藏的元素(如display:none)不会出现在渲染树中。
  4. Layout(布局)

    • 根据渲染树中每个节点的计算样式,浏览器进行布局计算(也被称为“重排”或“回流”)。浏览器根据CSS盒模型和其他布局信息,确定每个节点在视口中的确切位置和大小。
  5. Paint(绘制)

    • 在布局完成后,浏览器按照渲染树从后往前进行绘制,也就是从最底层的背景色和图像开始,逐层绘制文本、边框以及其他可视内容。这个过程包括合成层的创建、栅格化和渲染。
  6. Composite(合成)

    • 对于那些拥有层叠上下文的元素,浏览器还会执行复合操作(Compositing),将独立图层合成为最终的页面图像。层叠上下文允许元素在Z轴方向上独立渲染,从而实现动画、透明度和其他高级效果。
  7. 更新与重绘

    • 当DOM或CSS发生变化时,部分或全部渲染流程需要重新执行,可能涉及局部或全局的重排、重绘和合成。现代浏览器尽可能优化这个过程,只重新渲染受影响的部分。

在整个渲染过程中,浏览器通常会尽可能地将工作推迟到下一帧的渲染周期,以此提高页面性能和响应速度。此外,像Chrome等现代浏览器还会利用硬件加速功能,通过GPU协助完成一些复杂的图形渲染操作。 juejin.cn/post/684490…

重绘与回流

juejin.cn/post/706407…

在浏览器渲染过程中,重绘(Repaint)与重排(Reflow,也称为回流)是两种重要的更新机制,它们关乎页面性能和用户体验。

重排(Reflow)

  • 当一个元素的几何属性(如宽、高、外边距、内边距、定位等)发生变化,或者DOM树结构发生改变(如新增、删除、移动DOM元素)时,浏览器需要重新计算元素及其相关联元素的布局和位置。这个过程涉及对渲染树中所有受影响元素重新布局,即重新计算它们的几何信息,这会触发回流操作。
  • 回流不仅影响触发它的单个元素,还可能影响到周围布局,因为它可能导致整个文档流乃至整个视窗区域内的元素重新布局。
  • 回流通常代价较高,因为它会引发一系列连锁反应,可能导致大量计算和渲染工作。

重绘(Repaint)

  • 重绘则是指当元素的外观属性(如颜色、背景色、边框样式、背景图像等)发生变化,但元素的几何尺寸和位置没有改变时,浏览器仅需要更新屏幕上该元素的像素信息,而不必重新计算布局。
  • 重绘比重排的性能开销较小,因为它不需要重新计算元素的布局,而是直接刷新屏幕上的某些像素区域。

优化策略: 由于重排和重绘会影响页面性能,特别是在大规模或频繁变动时,因此前端开发者应该尽量减少不必要的重排和重绘。可以通过以下方式来优化:

  • 避免不必要的DOM操作,特别是改变元素几何属性的操作。
  • 批量修改DOM和样式,而不是逐个修改。
  • 使用CSS3 transform 和 opacity 属性进行动画,它们通常不会触发重排,而只会触发重绘或合成层更新。
  • 利用硬件加速特性,减少CPU负担。

总之,在实际开发中,理解和掌握重排与重绘的触发条件及优化方法对于提升网页性能至关重要。

浏览器的缓存策略

juejin.cn/post/684490…

浏览器缓存策略是浏览器为了提高网页加载速度和减少网络带宽消耗而采取的一种机制,它允许浏览器在满足一定条件时,直接从本地缓存中加载资源而不是重新向服务器请求。浏览器缓存策略主要分为两大类:强缓存和协商缓存。

强缓存(也称为绝对缓存)

  • Expires:服务器在响应头中设置一个到期时间,如果在这个时间内,浏览器认为缓存内容依然有效,则直接从缓存中加载资源,不再向服务器发送请求。
  • Cache-Control:优先级高于Expires,它支持更多的缓存指令,如max-age(指定缓存的有效时间,单位秒)、no-cache(要求验证缓存)、no-store(禁止缓存)等。

协商缓存(也称为条件GET或对比缓存)

  • Last-Modified / If-Modified-Since:服务器在响应头中添加Last-Modified表示资源最后修改时间,浏览器在下次请求时带上If-Modified-Since,询问服务器资源是否已更新,如果服务器确认资源未变化,则返回304 Not Modified,浏览器继续使用缓存中的资源。
  • ETag / If-None-Match:服务器为每个资源生成一个唯一的ETag(实体标签),浏览器请求时带上If-None-Match,询问服务器资源是否有新的ETag,如果没有变化,则返回304 Not Modified。

浏览器在发起请求时会先检查强缓存策略,如果强缓存未命中的情况下才会采用协商缓存策略。这两种策略结合使用,能够有效提高网页加载速度,减少不必要的网络传输,并保证在资源更新时及时获取最新版本。

线程与进程

juejin.cn/post/699184…

juejin.cn/post/684490…

线程(Thread)和进程(Process)是操作系统中两种重要的抽象概念,它们都是实现并发和并行计算的基础单位,但有不同的层次和侧重点:

进程

  • 进程是操作系统资源分配和保护的基本单位,每个进程都有自己独立的地址空间,包含代码、数据、堆、栈等资源,以及打开的文件描述符、信号处理函数等系统资源。
  • 进程之间是相互隔离的,也就是说,一个进程不能直接访问另一个进程的内存空间,若要通信,需要借助IPC(进程间通信)机制,如管道、消息队列、共享内存、套接字等。
  • 操作系统调度的基本单位是进程,每个进程可以有多个线程,但至少有一个主线程。

线程

  • 线程是进程中执行运算的最小单位,是进程中实际运作的实体,它负责执行一系列指令序列。
  • 线程共享进程的资源,如地址空间、全局变量、文件描述符等,因此多个线程可以访问相同的内存地址,但也需要同步机制防止数据竞争。
  • 线程有自己的程序计数器、堆栈和局部变量,但在同一进程中的线程切换代价相比进程切换要小得多。
  • 线程可以并发执行,即在一个进程中可以同时有两个或更多的线程在运行,从而提高程序的执行效率和响应速度。

简而言之,进程是资源拥有者,线程是资源使用者,线程是操作系统调度的更细粒度单元。多线程技术使得在一个进程中可以实现多个并发活动,充分利用CPU资源,而多进程技术则允许多个独立的任务同时在系统中运行。

浏览器中的进程与线程

浏览器是一个包含多个进程和多个线程的复杂软件系统。浏览器本身是由多个进程构成的,而每个进程中又有多个线程协同工作。

  • 进程层面: 浏览器通常会为每个打开的标签页、扩展或插件创建单独的进程,这样做的好处是提高了浏览器的稳定性,一个标签页或者插件崩溃不会影响其他标签页。例如,Google Chrome浏览器就采用了多进程架构,每个Tab页(或者其他独立的渲染上下文)都在各自的渲染进程中运行。

  • 线程层面: 每个浏览器进程内部包含多个线程,例如:

    • GUI线程:负责处理用户界面事件和渲染网页。
    • JS引擎线程:负责执行JavaScript代码,由于JavaScript是单线程的,因此在单个JS上下文中执行JavaScript代码时,同一时间只能执行一段代码。
    • 渲染线程:负责解析HTML、CSS并将其渲染成可视界面,与JS引擎线程互斥。
    • 网络线程:处理HTTP请求和响应。
    • 定时器线程:处理setTimeout和setInterval等定时任务。
    • 事件触发线程:处理各种事件,如鼠标点击、键盘敲击、页面加载等。
    • 音频、视频解码线程:处理多媒体流的播放和解码。

总的来说,浏览器是一个多进程架构,每个进程内部又包含多个线程协同工作,以实现高效的并发处理和良好的用户体验。

JS与单线程

JavaScript引擎在浏览器中的执行确实是单线程的,即JavaScript代码在一个给定的上下文中(如浏览器Tab页)只能通过一个主线程执行。然而,浏览器本身并非单线程,它是一个多进程或多线程环境。具体到浏览器的一个Tab页,虽然JavaScript执行环境是单线程的,但浏览器为每个Tab页通常会分配一个渲染进程,这个进程中除了包含处理JavaScript的线程之外,还有其他的线程负责不同的任务,比如渲染线程、网络请求线程、事件处理线程等。

JavaScript在浏览器环境中的执行环境是单线程的,这主要是出于历史原因和安全性考虑,因为JavaScript最初设计是用来在浏览器中执行脚本,以增强网页的交互性,如果允许多个线程随意修改DOM,将会产生难以预料的结果和同步问题。

在JavaScript的单线程模型中,所有的任务(同步任务和异步任务)都放在一个执行栈(Call Stack)中按序执行。同步任务会按照代码的书写顺序逐个执行,而异步任务(如网络请求、定时器等)则会被放到任务队列(Task Queue)中,等待主线程空闲时(也就是执行栈为空时)通过事件循环(Event Loop)机制被推送到执行栈中执行。

异步编程模型通过回调函数、Promise、Generator函数(配合co模块或async/await)以及Async/Await等方式来实现非阻塞式的任务处理,使得即便在单线程环境下,JavaScript也能高效地处理异步任务而不阻塞UI线程,保持页面的响应性。

此外,为了更好地利用多核CPU资源,现代浏览器提供了Web Workers API,允许JavaScript在后台创建独立的工作者线程(Worker Threads),这些线程可以独立于主线程运行,执行计算密集型或I/O密集型任务,但它们不能直接操作DOM,而是通过消息传递与主线程通信。而对于Node.js环境,虽然其JavaScript运行环境也是单线程,但底层的V8引擎加上libuv库支持异步I/O操作,使其在处理I/O任务时能充分利用系统资源,表现出类似异步多线程的效果。

RESTful API

RESTful API(Representational State Transfer,表述性状态转移)是一种基于HTTP协议的Web服务接口设计风格,由Roy Fielding博士在其博士论文中提出。RESTful API的设计原则体现了Web体系架构的约束和优势,提倡以资源为中心,利用HTTP方法(GET、POST、PUT、PATCH、DELETE等)来操作资源,实现客户端和服务器之间的无状态交互。

以下是RESTful API的主要特点和设计原则:

  1. 资源导向:API设计围绕资源展开,每个资源都有唯一的URI(Uniform Resource Identifier),如 /users/{id} 代表用户资源集合中的一个具体用户。

  2. HTTP方法的语义

    • GET:从服务器获取资源的表示,幂等操作,一般用于检索数据。
    • POST:向指定资源提交数据,请求被处理后通常会产生新资源的创建。
    • PUT:替换服务器上指定资源的全部内容。
    • PATCH:更新服务器上指定资源的部分内容。
    • DELETE:删除服务器上的指定资源。
  3. 无状态通信:每次请求中包含处理请求所需的所有信息,服务器不保存客户端的任何上下文信息,每个请求都是独立的事务。

  4. 统一接口:所有资源均通过相同的接口和同样的HTTP方法进行操作,以统一的方式来处理资源的增删改查。

  5. 可缓存性:通过HTTP协议的缓存机制(如Cache-Control、ETag等头信息),提高性能和减少服务器负载。

  6. 层次性资源结构:URI结构可以反映出资源的层级关系,如 /books/{bookId}/chapters/{chapterId}

  7. 自描述性:通过HTTP响应头和链接关系(Link Header或HAL、JSON-LD等格式的链接对象),提供足够的元数据描述资源及其操作。

  8. 标准状态码:每个响应都带有恰当的HTTP状态码,如200表示成功,404表示未找到资源,500表示服务器内部错误等,便于客户端理解请求结果。

通过遵循这些原则设计API,RESTful API易于理解、扩展和维护,有助于构建松耦合的分布式系统,并支持跨平台、跨语言的客户端与服务器进行交互。

响应式设计

响应式设计(Responsive Design)是一种网页设计方法论,旨在使网页布局和内容能够根据不同设备的屏幕尺寸、方向以及用户的操作方式做出适应性变化,从而提供最佳的用户体验。响应式设计的目标是在不牺牲视觉美感和功能完整性的情况下,确保网页在多种设备上,包括桌面电脑、笔记本电脑、平板电脑、智能手机乃至未来的新型设备上都能流畅显示和交互。

响应式设计的关键要素包括:

  1. 流动性(Fluid Grids) :使用百分比而非固定像素来定义网页布局,使得页面元素可以根据浏览器窗口大小自动调整布局和尺寸。
  2. 可伸缩的图片和媒体:使用CSS3的max-width: 100%等属性让图片和其他媒体内容随容器大小自动缩放,始终保持在容器内适配显示。
  3. 媒体查询(Media Queries) :根据设备的视口宽度、设备像素比等因素应用不同的CSS样式,从而实现不同屏幕尺寸下的差异化布局。
  4. 自适应布局:根据设备特点重新安排布局,例如在窄屏设备上将菜单折叠成汉堡菜单,或调整内容区块的堆叠顺序。
  5. 触摸优化:在移动设备上,响应式设计还包括优化交互体验,比如增大触摸目标区域、支持滑动手势等。

响应式设计的出现顺应了互联网设备多样化的趋势,它倡导“一次编写,到处适应”的理念,极大地方便了开发者和设计师在多设备环境下制作和维护网站,同时确保用户无论使用何种设备,都能获得良好的浏览和使用体验。响应式设计已经成为现代Web开发不可或缺的标准实践。

微服务与微前端

juejin.cn/post/723602…

微服务 (Microservices) 是一种软件开发方法,其中复杂的单体应用被分解为一组小型、自治的服务。每个服务都围绕着特定的业务能力进行构建,并能够独立部署、扩展和维护。微服务的关键特征包括:

  1. 服务拆分:根据业务领域划分服务边界,每个服务专注于一项具体任务或业务逻辑。
  2. 自治性:每个微服务拥有自己的数据库和其他资源,能独立运行。
  3. 轻量级通信:服务之间通过API(如RESTful接口)、消息队列或事件驱动机制进行交互。
  4. 技术异构性:各个服务可以采用不同的技术栈和编程语言。
  5. 独立部署:每个服务可以独立编译、测试和部署,无需与其他服务协调,降低了风险和复杂性。
  6. 容错性增强:一个服务出现问题不会影响其他服务,提高了整体系统的可用性和稳定性。

微前端 (Micro Frontends) 则是在前端架构领域的概念,它借鉴了微服务的思想,将单一的大型前端应用拆分成多个小型、独立的前端应用,每个应用都可以独立开发、测试、部署和版本控制。微前端的主要特点包括:

  1. 拆分用户界面:将Web应用的UI层划分为多个小型前端应用,各自负责一部分业务功能。
  2. 独立交付与集成:每个微前端应用可以由不同的团队使用不同的技术栈开发,然后在运行时通过主框架集成到同一个页面上。
  3. 技术栈无关:各微前端应用之间互不影响技术决策,可以自由选择适合自己的前端框架和工具链。
  4. 降低耦合:避免大规模重构和回归测试,因为修改和升级一个部分不影响其他部分。
  5. 按需加载:提高性能,仅加载需要的功能对应的前端应用部分,而不是一次性加载整个应用。

总结起来,微服务和微前端都是为了应对复杂性增长、加速迭代速度、适应组织架构灵活性以及提升可维护性的需求而提出的架构模式,分别对应后端服务架构和前端应用架构。

事件循环机制

jakearchibald.com/2015/tasks-… juejin.cn/post/691420…

JavaScript事件队列(Event Queue)和事件循环(Event Loop)是JavaScript运行时环境(如浏览器环境)中处理异步任务的核心机制。JavaScript引擎是单线程的,这意味着在同一时间内只能执行一段代码。为了解决异步处理问题,引入了事件队列和事件循环机制。

事件队列(Event Queue) : 事件队列是一个存放异步任务回调函数的有序列表。当JavaScript执行过程中遇到异步操作(如定时器、网络请求、I/O操作等)时,不会立即执行其结果处理函数,而是将其放到事件队列中排队等待。事件队列可以包含多个不同的队列,比如宏任务队列(Macro Task Queue)和微任务队列(Micro Task Queue)。

宏任务(Macro Tasks) : 宏任务主要包括:

  • setTimeout 和 setInterval 回调函数
  • I/O 操作完成后触发的回调
  • UI 渲染完成后触发的回调(浏览器环境中)
  • requestAnimationFrame 回调
  • Node.js 中的 setImmediate

微任务(Micro Tasks) : 微任务通常在当前宏任务执行完毕,但在下一个宏任务执行之前执行,优先级更高,主要包括:

  • Promise 的 .then.catch 和 .finally 方法注册的回调
  • MutationObserver 的回调
  • queueMicrotask 函数注册的回调

事件循环(Event Loop) : 事件循环机制是不断监控和协调事件队列和执行栈的过程。它的工作流程如下:

  1. 执行全局脚本或调用栈中的同步代码。
  2. 当调用栈为空时,检查微任务队列是否有待执行的任务,如果有,则取出并执行所有微任务。
  3. 执行完所有微任务后,开始执行下一个宏任务。
  4. 宏任务执行完毕后再次回到第二步,检查微任务队列。
  5. 如此反复循环,直至事件队列为空。

举例说明:

Javascript
console.log('1');

setTimeout(() => {
  console.log('2');
});

new Promise((resolve) => {
  resolve();
}).then(() => {
  console.log('3');
});

console.log('4');

在上述代码中,同步代码首先执行,输出'1'和'4'。随后,setTimeout注册的宏任务被放入宏任务队列,Promise.then方法注册的微任务被放入微任务队列。在本次事件循环中,同步代码执行完毕后,立即执行微任务队列中的所有任务,输出'3'。接下来的一个事件循环轮询中,才会执行宏任务队列中的setTimeout回调,输出'2'。

这种事件驱动的异步模型保证了JavaScript引擎在处理异步任务时既能保持单线程执行,又能实现异步处理,使得Web应用能够在等待异步操作的同时处理用户交互和其他同步任务。

CDN

juejin.cn/post/684490…

内容分发网络(Content Delivery Network, CDN)是一种分布式网络服务,旨在通过在全球范围内设立多个边缘服务器节点,将网站内容和服务(如静态网页、图片、视频、脚本等)缓存并分发到接近用户的地理位置。当用户访问网站时,CDN会将请求引导至最近的边缘服务器,从而大幅缩短数据传输距离,提高内容加载速度,优化用户体验,减轻源站服务器的压力,并提高网站的可用性和扩展性。

使用CDN的主要原因包括:

  1. 提高内容加载速度:通过减少内容传输距离,降低网络延迟,从而提升用户访问速度,尤其是对于多媒体内容丰富的网站或面向全球用户的网站。
  2. 缓解源站服务器压力:CDN节点承担了大部分静态内容的分发任务,使得源站服务器不必处理所有用户的请求,从而降低了服务器负载,提高了网站的并发处理能力。
  3. 提高可用性和容灾能力:由于CDN节点分散在多地,即使某个数据中心或网络出现故障,其他节点仍能继续提供服务,确保网站内容始终可访问。
  4. 节省带宽成本:通过缓存和就近分发,减少了跨国或跨地区的大流量数据传输,可以显著降低源站的带宽费用。
  5. 防DDoS攻击:CDN自带一定的流量清洗和负载均衡能力,能在一定程度上抵御分布式拒绝服务(DDoS)攻击,保护源站服务器不受攻击影响。
  6. SEO优化:页面加载速度是搜索引擎排名因素之一,CDN可以提升网站性能,有利于搜索引擎优化(SEO)。

综上所述,CDN成为了现代互联网基础设施中不可或缺的部分,对于提升网站性能、保证服务质量、节约成本等方面都有重要意义。

DNS

DNS(Domain Name System,域名系统)是一种分布式数据库服务,用于将易于记忆的域名(如www.example.com)转换为计算机网络中用于寻址的IP地址(如192.0.2.1)。DNS使得用户和应用程序无需记住复杂的数字IP地址,只需通过简洁易读的域名即可访问互联网上的资源。

使用DNS的原因主要包括:

  1. 人机友好性:域名系统提供了一种更为人性化的方式来标识互联网上的服务器和网络资源,便于用户记忆和输入。
  2. 路由与寻址:在互联网中,数据包的传输依赖于IP地址。DNS充当了桥梁,将人们熟知的域名转化为机器可以理解的IP地址,使得数据可以从源主机准确地送达目标主机。
  3. 负载均衡与冗余:DNS可以通过记录(RR, Resource Records)的轮询、权重分配或其他智能调度策略,将用户请求导向不同服务器,实现负载均衡,同时提供冗余以防止单点失效。
  4. 分布式管理:DNS采用分布式数据库架构,允许域名所有权人将域名管理权分散在世界各地的DNS服务器上,提高了整个互联网的稳定性和可靠性。
  5. 安全与认证:DNS还支持DNSSEC等安全扩展,可以对域名数据进行签名以防止中间人攻击和域名劫持,从而加强互联网的安全性。

因此,DNS是互联网运作的基础服务之一,它确保了用户能够便捷、准确且高效地访问全球范围内的网络资源。

网关

网关(Gateway)在计算机网络和分布式系统中扮演了一个重要的角色,它是一个位于不同网络或子系统之间的节点,负责处理进出这些网络或子系统的流量,并执行协议转换、安全控制、数据过滤、负载均衡、API管理等任务。网关的存在主要是为了解决以下几个问题:

  1. 协议转换:不同的系统可能使用不同的通信协议,网关能够将一种协议的请求转换为另一种协议,使得原本不兼容的系统能够相互通信。
  2. 安全控制:网关可以作为一个安全屏障,执行身份验证、授权、防火墙策略等安全措施,保护内部网络不受外部攻击,同时确保数据传输的安全性。
  3. 路由选择:在大型分布式系统或微服务架构中,网关可以作为服务入口,根据请求路径和内容将流量路由到相应的后端服务,简化客户端与多个服务间的通信。
  4. API管理:API网关(API Gateway)可以统一处理API请求,实现请求的聚合、认证、限流、熔断、监控等功能,为API消费者提供一致且安全的服务接口。
  5. 数据过滤和格式化:网关可以对传输的数据进行清洗、转换或格式化,确保数据符合下游系统的要求。
  6. 负载均衡:在集群环境中,网关可以作为负载均衡器,将客户端的请求均匀地分发到后端的多个服务器,提高系统的可用性和可扩展性。
  7. 设备兼容性:在物联网(IoT)场景中,网关还可以处理不同设备间的协议差异,使得各类智能设备能与云端或其它设备顺利沟通。

总之,网关就像是不同网络或系统间的交通警察,负责管理和协调不同环境之间的交互,确保通信顺畅、安全、可控。

HTTP状态码

HTTP状态码(HTTP Status Codes)是HTTP协议中用于表示服务器对客户端请求的响应状态的标准格式代码,通常是一个三位数字。这些状态码对客户端和服务器之间的通信有着重要的指示作用,帮助开发者和用户理解请求是否成功、为何失败以及下一步应该做什么。以下是HTTP状态码的主要分类和部分常见状态码及其含义:

  1. 1XX(临时响应) :信息性状态码,表示服务器正在处理请求,但尚未完成。

    • 100 Continue:客户端可以继续发送请求正文。
    • 101 Switching Protocols:服务器正在切换协议。
  2. 2XX(成功) :表示请求已经被成功接收、理解和接受。

    • 200 OK:请求成功,请求的数据或操作成功完成。
    • 201 Created:请求已被成功处理,并创建了新资源。
    • 202 Accepted:服务器已接受请求,但还未处理完成。
    • 204 No Content:请求成功,但响应体不包含任何内容。
  3. 3XX(重定向) :需要进一步操作才能完成请求。

    • 301 Moved Permanently:被请求的资源已永久移动到新位置。
    • 302 Found 或 307 Temporary Redirect:临时重定向,资源暂时存在于不同的URI下。
    • 303 See Other:请求应当使用 GET 方法获取另一个 URI 上的资源。
    • 304 Not Modified:客户端缓存依然有效,服务器未对资源内容做出修改。
  4. 4XX(客户端错误) :客户端似乎发生了错误。

    • 400 Bad Request:服务器无法理解请求,可能是由于格式错误等原因。
    • 401 Unauthorized:请求未经授权,需要提供有效的身份验证凭证。
    • 403 Forbidden:服务器理解请求,但拒绝执行它。
    • 404 Not Found:服务器找不到请求的资源。
    • 405 Method Not Allowed:请求方法(如 POST、PUT 等)不被允许。
  5. 5XX(服务器错误) :服务器遇到了意外情况,无法完成请求。

    • 500 Internal Server Error:服务器遇到了未知错误,无法完成请求。
    • 501 Not Implemented:服务器不支持请求的功能。
    • 502 Bad Gateway:作为网关或代理工作的服务器收到了无效响应。
    • 503 Service Unavailable:服务器当前无法处理请求,通常由于服务器过载或维护。
    • 504 Gateway Timeout:作为网关或代理工作的服务器未及时从上游服务器收到请求。

每一种状态码都有其特定的意义,有助于客户端和服务器之间进行有效的通信和错误处理。

POST和GET

juejin.cn/post/684490…

HTTP报文

HTTP(HyperText Transfer Protocol,超文本传输协议)报文是HTTP协议中客户端与服务器之间进行通信的数据块,它包括请求报文和响应报文两种类型,每种类型的报文都有其特定的结构。

HTTP 请求报文结构

  1. 请求行(Request Line)

    • 包括请求方法(如GET、POST、PUT、DELETE等)、请求URI(Uniform Resource Identifier)和HTTP版本号。
    • 示例:GET /index.html HTTP/1.1
  2. 请求头(Request Headers)

    • 一系列键值对,用于提供有关请求的附加信息,如客户端信息(User-Agent)、接受类型(Accept)、内容长度(Content-Length)、授权信息(Authorization)等。

    • 示例:

      Code
      Host: example.com
      Accept-Language: en-US,en;q=0.5
      Content-Type: application/x-www-form-urlencoded
      
  3. 空行(Blank Line)

    • 请求头和请求正文之间有一个空行(CRLF,即回车换行)用于区分两者。
  4. 请求正文(Request Body,可选)

    • 若请求方法允许或需要携带请求数据(如POST、PUT请求),则在空行之后跟随的就是请求正文,用于承载具体的请求内容,如表单数据、JSON、XML等。

HTTP 响应报文结构

  1. 状态行(Status Line)

    • 包括HTTP版本号、状态码(如200、404、500等)和状态消息(Reason-Phrase)。
    • 示例:HTTP/1.1 200 OK
  2. 响应头(Response Headers)

    • 类似于请求头,包含服务器相关信息,如服务器类型(Server)、内容类型(Content-Type)、内容长度(Content-Length)、缓存控制(Cache-Control)等。

    • 示例:

      Code
      1Server: Apache/2.4.1
      2Content-Type: text/html; charset=UTF-8
      3Content-Length: 1234
      
  3. 空行(Blank Line)

    • 响应头和响应正文之间同样有一个空行(CRLF)作为分隔。
  4. 响应正文(Response Body,可选)

    • 包含服务器返回给客户端的数据,可以是HTML文档、JSON数据、图片或其他任何类型的数据。

总体来看,HTTP报文的结构清晰明了,方便客户端和服务器进行通信交互。对于每个报文,起始行和头部信息是必不可少的,正文则根据请求或响应的具体需求来确定是否存在。随着HTTP协议的发展,报文结构在不同版本中有所扩展,但基本框架保持一致。

TCP三次握手与四次挥手

TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,在网络通信中确保数据的可靠传输。TCP建立连接和断开连接分别经历了著名的“三次握手”(Three-Way Handshake) 和“四次挥手”(Four-Way Handshake) 过程。

三次握手 (Three-Way Handshake)

  1. 第一次握手 (SYN) :

    • 客户端想要与服务器建立连接时,它会随机生成一个初始序列号(ISN),然后发送一个SYN(同步序列编号Synchronize Sequence Numbers)报文段给服务器。这个报文段中包含客户端的初始序列号(seq = x)。
    Code
    1客户端 -> 服务器: SYN(seq=x)
    
  2. 第二次握手 (SYN + ACK) :

    • 服务器接收到客户端的SYN报文段后,确认客户端发起连接请求,并且也随机生成自己的初始序列号(ISN)。服务器返回一个SYN报文段的同时携带一个ACK(确认Acknowledgement)报文段,其中确认号ack设置为x+1(即客户端的序列号加1),表示已经收到了客户端的SYN;同时带上自己的序列号seq=y。
    Code
    1服务器 -> 客户端: SYN(seq=y), ACK(ack=x+1)
    
  3. 第三次握手 (ACK) :

    • 客户端收到服务器的SYN+ACK报文段后,需要对服务器的SYN进行确认。因此,客户端再次发送一个ACK报文段,确认号ack设置为y+1(即服务器的序列号加1),表示已收到服务器的SYN。至此,双方都已确认对方的初始序列号,且都知道对方已准备好建立连接。
    Code
    1客户端 -> 服务器: ACK(ack=y+1)
    

经过这三次握手之后,客户端和服务器就建立了可靠的TCP连接,可以开始传输数据。

四次挥手 (Four-Way Handshake)

  1. 第一次挥手 (FIN) :

    • 当某一方(例如客户端)完成数据传输任务或者打算关闭连接时,它会向另一方(例如服务器)发送一个FIN(结束Finish)报文段,请求关闭从客户端到服务器的数据传输通道。此时,客户端进入FIN_WAIT_1状态。
    Code
    1客户端 -> 服务器: FIN(seq=u)
    
  2. 第二次挥手 (ACK) :

    • 服务器接收到客户端的FIN报文段后,确认该请求,此时服务器知道客户端不再有新的数据发送过来,但仍可能继续向客户端发送数据。服务器回应一个ACK报文段,确认号ack设置为u+1,表示已收到客户端的FIN。服务器进入CLOSE_WAIT状态,而客户端进入FIN_WAIT_2状态。
    Code
    1服务器 -> 客户端: ACK(ack=u+1)
    
  3. 第三次挥手 (FIN) :

    • 服务器完成所有数据的发送后,也会发送一个FIN报文段给客户端,请求关闭从服务器到客户端的数据传输通道。
    Code
    1服务器 -> 客户端: FIN(seq=v), ACK(ack=u+1)
    
  4. 第四次挥手 (ACK) :

    • 客户端接收到服务器的FIN报文段后,同样发送一个ACK报文段作为回应,确认号ack设置为v+1,表示已收到服务器的FIN。此时,客户端等待一段时间(通常称为TIME_WAIT状态,防止最后确认报文段在网络中丢失)后彻底关闭连接。服务器在接收到客户端的ACK后立即关闭连接。
    Code
    1客户端 -> 服务器: ACK(ack=v+1)
    

以上就是TCP连接建立与终止过程中的三次握手与四次挥手的详细描述。这些机制确保了数据传输的可靠性和连接的有序建立与释放。

HTTP3

juejin.cn/post/684490… HTTP/1.x、HTTP/2 和 HTTP/3 是超文本传输协议(HTTP)的三个主要版本,各自有显著的特点和改进之处。下面是这三个版本之间主要的区别:

HTTP/1.x

  • 特点

    • HTTP/1.0 和 HTTP/1.1 是广泛应用的传统版本。
    • HTTP/1.1 引入了持久连接(Persistent Connections),允许在一个TCP连接上发送多个HTTP请求和响应,但存在队头阻塞(Head of Line Blocking)问题,即一个请求的响应必须等待前面请求完成才能开始传输。
    • HTTP/1.1 还增加了缓存控制、分块传输编码、host头部字段等改进。

HTTP/2

  • 特点

    • HTTP/2 最大的改进是引入了多路复用(Multiplexing),允许在一个TCP连接上并行处理多个请求和响应,解决了HTTP/1.x中的队头阻塞问题,大幅度提升了页面加载速度。
    • HTTP/2 使用二进制分帧(Binary Framing),将HTTP消息分解为更小的帧,提高了协议解析效率和灵活性。
    • 头部压缩(Header Compression),通过HPACK算法对请求和响应头部进行压缩,减少不必要的网络传输量。
    • 服务器推送(Server Push),服务器可以在客户端请求前主动推送相关资源。

HTTP/3

  • 特点

    • HTTP/3 最大的变化是抛弃了TCP,转而基于QUIC协议,QUIC是一种基于UDP的可靠传输协议,集成了TLS加密,实现了更低的延迟和更快的连接建立。
    • 保留了HTTP/2的多路复用优势,但基于QUIC的多路复用机制更加强大,因为它在传输层就已经支持多路复用,而且具备快速恢复机制,对丢包有更好的应对能力。
    • 由于QUIC内置了TLS加密,HTTP/3比HTTP/2的加密传输速度更快,且更安全。

总结来说,HTTP/2 和 HTTP/3 都致力于提高网络性能,减少延迟,而HTTP/3在HTTP/2的基础上进一步改进了传输层的性能和安全性。

客户端识别与cookie机制

juejin.cn/post/684490…

客户端识别是Web应用程序和服务识别和追踪用户会话的过程。在HTTP协议中,由于其原始设计是无状态的,这意味着服务器在处理完客户端的一次请求后,如果不借助额外的机制,无法关联到后续的请求。为了弥补这一缺陷,Cookie机制应运而生,用于维持客户端与服务器之间某种形式的状态。

Cookie机制

  1. 工作原理

    • 当客户端首次向服务器发起请求时,服务器可以根据业务逻辑创建一个Cookie,并通过HTTP响应头Set-Cookie将其发送给客户端。
    • 客户端收到Cookie后,将其保存在本地(浏览器的Cookie存储区)。
    • 之后客户端每次向同一服务器发起请求时,都会自动在HTTP请求头Cookie中带上之前服务器设定的Cookie。
    • 服务器通过检查请求头中的Cookie信息,就可以识别出客户端的身份和相关的会话状态。
  2. Cookie属性

    • Cookie可以包含多种属性,如expires(生命周期)、path(作用路径)、domain(作用域域名)、secure(仅在HTTPS下传输)、HttpOnly(禁止JavaScript访问该Cookie)等。
    • SameSite属性用于限制第三方Cookie的发送策略,以增强安全性。
  3. 跨站请求(CORS)与Cookie

    • 当涉及到跨域资源共享(CORS)时,crossorigin属性可以用来指示是否允许跨域访问Cookie,以及是否需要发送认证信息。
    • anonymous表示在跨域请求时不携带验证信息,而use-credentials则表示携带验证信息,如Cookie。
  4. 安全性

    • 使用Cookie进行客户端识别时,需注意隐私和安全问题,不应滥用Cookie来追踪用户的行为,特别是在没有明确告知用户和获得同意的情况下。
    • 使用SecureHttpOnly属性可以帮助增加Cookie的安全性,防止恶意脚本盗取或篡改Cookie信息。
  5. 替代方案

    • 除了Cookie以外,还有其他客户端识别的技术,如Token-based身份验证(JWT、OAuth等),或者利用HTML5的localStorage和sessionStorage等Web Storage技术进行客户端状态管理。

总之,Cookie机制在客户端识别和会话管理中扮演着核心角色,允许Web应用程序维持状态并个性化用户交互。但同时也伴随着一定的安全风险和隐私考虑,因此在实际应用中需要谨慎设计和使用。

代理服务器与反向代理以及负载均衡

代理服务器(Proxy Server) : 代理服务器作为一个中间层,主要用于客户端与服务器之间的通信。当客户端发起请求时,请求首先被发送到代理服务器,代理服务器接收到请求后,根据配置决定是否直接将请求传递给目标服务器,或者根据其他条件(如缓存策略)处理请求。代理服务器可以用于:

  1. 匿名访问:通过隐藏客户端的IP地址,保护用户隐私。
  2. 缓存服务:代理服务器可以缓存常用或静态资源,减少对目标服务器的请求次数,提高访问速度。
  3. 访问控制:企业或组织可以设置代理服务器,对内部网络用户的互联网访问行为进行管理和限制。
  4. 内容过滤:可以过滤或阻止访问某些不安全或不适合的网站内容。

反向代理(Reverse Proxy) : 反向代理与代理服务器相反,它位于服务器端,对外面的客户端而言就像是实际的服务端。客户端直接向反向代理服务器发送请求,反向代理服务器负责将请求转发到内部的后端服务器群,并将后端服务器的响应返回给客户端。反向代理的主要作用包括:

  1. 负载均衡:通过转发机制将请求分发到多个后端服务器,平衡服务器负载,提高系统整体性能和可用性。
  2. 安全防护:隐藏真实服务器地址,提供额外的安全屏障,如WAF(Web应用防火墙)功能,抵挡DDoS攻击等。
  3. 内容缓存:对一些静态或不太频繁变化的内容进行缓存,减轻后端服务器压力。
  4. 统一入口点:简化网络架构,提供统一的接入点,便于管理和维护。

负载均衡(Load Balancing) : 负载均衡是一种服务器集群管理技术,目的是在多台服务器间分配网络负载,以确保服务的高性能、高可用性和可扩展性。反向代理常常与负载均衡相结合,通过一定的策略(如轮询、最少连接数、权重分配等)将客户端请求分配给后端服务器集群中的某一节点。这样,即使在高并发情况下,也能保证服务的稳定性和响应速度。

总结来说,代理服务器和反向代理分别从客户端和服务器端的角度出发,实现不同的功能,而反向代理经常作为负载均衡解决方案的一部分,用于优化服务器集群的性能和可用性。

正则表达式

正则表达式(Regular Expression,简称regex或regexp)是一种强大而灵活的文本处理工具,它是一种模式匹配语言,用于描述和匹配字符串中的字符组合。正则表达式被广泛应用于各种编程语言和文本处理软件中,用于搜索、替换、分割文本,以及验证字符串是否符合特定格式。

正则表达式的组成部分通常包括:

  1. 元字符:如.(匹配任意单个字符,除换行符外)、\d(匹配数字)、\w(匹配字母、数字或下划线)、\s(匹配空白字符)等。
  2. 量词:如*(零次或多次)、+(一次或多次)、?(零次或一次)、{m,n}(m到n次)等,用来描述前面元素的重复次数。
  3. 字符类:方括号[]用于定义一组可选字符,如[abc]匹配'a'、'b'或'c'。
  4. 分组和引用:圆括号()用于分组,同时也可以用于后向引用或捕获组。如(\w+)\s+\1会匹配连续的两个相同的单词。
  5. 边界匹配:如^匹配字符串的开始,$匹配字符串的结束,\b匹配单词边界。
  6. 选择和排除:竖线|用于提供选择项,[^abc]表示匹配除'a'、'b'和'c'之外的任何字符。
  7. 预定义字符类:例如\d(数字)、\D(非数字)、\w(单词字符)、\W(非单词字符)、\s(空白字符)、\S(非空白字符)等。

正则表达式的例子:

  • /^\d{3}-\d{2}-\d{4}$/ 匹配美国社保号码格式(如123-45-6789)。
  • /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/ 匹配电子邮件地址格式。

在实际编程中,正则表达式通常与字符串函数结合使用,如搜索(search)、替换(replace)、split等操作。在JavaScript中,你可以使用RegExp对象或字符串的原生方法来处理正则表达式。在Python、Java、Perl、PHP等其他语言中也有对应的正则表达式支持。

前端性能优化

juejin.cn/post/689299…

前端性能优化是一个广义的概念,它涵盖了一系列技术和策略,旨在减少页面加载时间、提升页面交互响应速度和流畅度。以下是一些主要的前端性能优化方式:

  1. 资源压缩与合并

    • 对CSS和JavaScript文件进行GZIP压缩,减少网络传输体积。
    • 将多个CSS和JavaScript文件合并为一个,减少HTTP请求的数量。
  2. 资源懒加载与预加载

    • 图片懒加载:只有当图片进入视窗时才开始加载,避免一开始加载过多不必要的图片造成带宽浪费。
    • 关键资源预加载:通过rel="preload"提前加载关键脚本或资源。
  3. CDN(Content Delivery Network)

    • 使用CDN分发静态资源,加快用户访问速度,减少延迟。
  4. 代码分离与动态加载

    • 使用Webpack等工具将代码分割成多个块,按需加载,例如通过import()动态加载模块。
    • 使用路由懒加载功能,在切换路由时只加载所需的组件和关联资源。
  5. 减少重排与重绘

    • 避免不必要的DOM操作,特别是影响布局的属性修改。
    • 批量操作DOM,尽量减少多次渲染。
    • 使用CSS3的transform和opacity属性进行动画,它们通常不会触发重排,只引起重绘或合成层更新。
  6. 缓存策略

    • 利用HTTP缓存头部(如Cache-Control、Expires、ETag等)指示浏览器缓存资源。
    • 使用Service Worker实现离线缓存或应用程序缓存。
  7. 资源优化

    • 压缩和优化图片,例如使用WebP格式、响应式图片SRCSET等。
    • 避免使用CSS import,改为内联或标签异步加载样式表。
    • 减少DNS查询,通过DNS预解析、减少域名更换等手段优化DNS查找速度。
  8. 首屏优化

    • 服务器端渲染(SSR):快速展示首屏内容,缩短用户感知的加载时间。
    • 通过Critical CSS提取首屏必要的CSS内容内联到HTML中,减少首次渲染的阻塞。
  9. 资源按需加载

    • 使用Intersection Observer API进行滚动时的内容加载。
  10. 减少第三方脚本影响

    • 控制第三方脚本的加载时机,避免影响页面渲染。
    • 评估第三方脚本的必要性,去掉冗余或低效的脚本。
  11. 利用硬件加速

    • 使用CSS3硬件加速特性,如transform: translateZ(0)开启GPU加速。
  12. 代码层面的优化

    • 删除无用的CSS和JavaScript代码。
    • 使用tree shaking和dead code elimination移除未使用的模块。

通过上述策略的综合运用,可以显著提升前端应用的性能表现,提高用户体验。随着Web技术的发展,新的性能优化技术也在不断涌现,前端开发者需要持续关注并学习新技术来保持性能优化的最佳实践。

前端模块化

前端模块化是针对传统JavaScript开发中存在的命名空间污染、依赖混乱、复用困难等问题提出的一种解决方案。模块化将一个大的程序分解成多个具有独立功能且具有良好封装的小模块,每个模块都有自己的作用域,只对外暴露必要的接口供其他模块调用,这样既方便代码管理,也有利于组件和功能的复用。

以下是前端模块化的几个发展阶段和相应的技术:

Shadow DOM

(Shadow DOM)是Web Components规范的一部分,它提供了一种封装和组合HTML内容和样式的机制,允许开发者创建具有独立、封装样式和行为的自包含组件。在Shadow DOM中,组件可以拥有自己的私有DOM树,这个私有DOM树被称为“影子DOM”(Shadow DOM subtree)。

在Shadow DOM中,样式(CSS)的作用范围限定在影子DOM内部,不会影响外部文档的样式,同样,外部文档的样式也不会污染组件内部。这样一来,开发者可以创建具备样式隔离性的自定义元素,增强组件的可重用性和可维护性。

使用Shadow DOM的基本方式是在元素上创建一个影子根(shadow root),然后在这个影子根中添加和操纵DOM元素,形成组件的内部结构。例如:

Javascript
// 创建一个自定义元素
class MyCustomElement extends HTMLElement {
  constructor() {
    super();
    
    // 创建影子根
    const shadowRoot = this.attachShadow({ mode: 'open' }); // 或 'closed'

    // 在影子根内部定义组件的DOM结构
    const template = document.createElement('template');
    template.innerHTML = `
      <style>
        /* 这里的样式只影响影子DOM内部 */
        div {
          color: red;
        }
      </style>
      <div>Hello, World!</div>
    `;

    // 将模板内容复制到影子DOM中
    const instance = template.content.cloneNode(true);
    shadowRoot.appendChild(instance);
  }
}

// 注册自定义元素
customElements.define('my-custom-element', MyCustomElement);

在上面的例子中,<my-custom-element>就是一个具有独立样式和结构的自定义元素,其内部的<div>元素的颜色设置只会影响该元素自身,而不会影响到页面上的其他<div>元素。这就是Shadow DOM的核心价值所在,即实现样式和DOM结构的封装与隔离。

Tree Shaking

Tree Shaking是一种优化JavaScript代码的方法,尤其是在使用模块化构建工具(如Webpack、Rollup等)的过程中,用于去除代码中未被引用的死代码(dead code),从而减小最终生成的bundle文件体积,提高应用加载速度。

在现代前端开发中,当我们使用ES6模块(或CommonJS等模块化方案)编写代码时,每个模块都只会导出那些明确标记为export的内容,并且其他模块只能通过import { specificExport } from 'module'这样的方式导入所需的部分。Tree Shaking正是利用这一特性,在编译和打包阶段分析模块间的依赖关系,识别哪些导出成员实际上没有被任何地方引用,然后将这些未引用的代码从最终的构建产物中移除。

简单来说,Tree Shaking就像是对整个代码库这棵大树进行摇晃,将那些“枯叶”(未使用的代码)从树上摇落下来,只保留真正被使用到的代码“果实”,达到精简代码的效果。这项技术之所以可行,是因为静态分析工具能够准确判断哪些模块成员在运行时不会被访问到,尤其是当使用支持静态分析的模块格式(如ES6模块)时效果更佳。

代码分割

代码分割(Code Splitting)是一种优化前端应用加载性能的技术,其原理是将原本庞大的单个JavaScript文件分割成多个小的代码块(chunks),这些代码块在需要时再异步加载,而不是一次性加载所有代码。这样可以显著减少初始页面加载时的下载量,提高页面的加载速度和用户体验。

在现代前端构建工具(如Webpack、Rollup)中,代码分割主要通过以下方式实现:

  1. 动态导入(Dynamic Import) :在JavaScript中使用动态导入语法(如import()函数),允许在运行时异步加载模块。当浏览器执行到动态导入语句时,才会发起网络请求加载对应的代码块。
  2. 路由分割(Route-based splitting) :对于单页应用(SPA),可以按照路由拆分代码,确保用户访问特定页面时才加载对应的模块。例如,在React Router或Vue Router中,可以为每个路由配置单独的代码块。
  3. 按需加载(Lazy Loading) :只有在组件第一次渲染或用户交互触发时才加载组件及其依赖的代码。
  4. 公共代码抽离(Commons Chunk) :将多个模块中共有的代码抽离出来,生成一个或多个公共代码块(common chunks),避免重复加载。

构建工具会分析项目的依赖关系图谱,将代码分割成合理的块,并生成对应的加载逻辑,确保代码在正确的时间和顺序被加载。当用户访问应用的不同部分时,对应的代码块通过异步请求加载到浏览器中,从而实现按需加载,避免加载未使用的代码,降低初始加载时间和总体资源体积。

CommonJs

CommonJS是Node.js生态中广泛采用的模块化规范,它基于文件和require()、module.exports两个核心API实现模块导入导出。每个JavaScript文件作为一个模块,有自己的私有变量和函数空间,通过require()加载其他模块,通过module.exports向外提供接口。

AMD (Asynchronous Module Definition)

AMD是由RequireJS推广的一种模块化规范,主要面向浏览器环境,特别适用于异步加载模块的场景。它通过define()函数定义模块,并使用require()加载模块,特点是支持异步加载和依赖前置。

UMD (Universal Module Definition)

UMD是一种通用模块定义,旨在让模块既可以用于CommonJS环境(如Node.js),又可以用于AMD环境,甚至在两者都不支持的情况下还能退化为全局变量模式,实现跨环境的模块加载。

ES6 Modules (ECMAScript 6 modules)

ES6模块是JavaScript标准化进程中的模块化方案,使用import和export关键字实现模块的导入导出。与CommonJS等相比,ES6模块在编译时就能确定模块依赖关系,且天然支持静态分析,有利于编译优化和Tree Shaking。

Webpack, Rollup 等模块打包工具

随着前端工程化的演进,Webpack、Rollup等模块打包工具极大地推动了前端模块化的实践。它们不仅能处理ES6模块,还能转换CommonJS模块,并通过loader和plugin机制进一步增强模块加载、转换和打包能力,支持代码分割、按需加载等功能,极大提升了前端项目的开发效率和运行性能。

在实际开发中,前端开发者可以根据项目需求选择合适的模块化方案,并借助构建工具进行模块的管理和优化,实现代码的解耦、复用和高效加载。

JSX

JSX 是 JavaScript XML 的缩写,它是 Facebook 在开发 React 库时引入的一种语法扩展,允许在 JavaScript 代码中编写类似于 XML/HTML 的结构化语法来创建 UI 组件。JSX 不是一种全新的编程语言,而是 JavaScript 的一种语法糖,它最终会被转换成合法的 JavaScript 对象,这些对象被称为 React 元素。

在 JSX 中,你可以直接在 JavaScript 代码中编写类似 HTML 的标签结构,但实际上这些标签会被解释为 React 组件的构造函数调用。例如:

Jsx
const element = <h1>Hello, world!</h1>;

这段 JSX 代码会被编译器转换为 JavaScript 代码,大概是这样的:

Javascript
const element = React.createElement('h1', null, 'Hello, world!');

JSX 的特点和优势包括:

  1. 组件化:通过 JSX 创建的元素实际上是 React 组件的实例,允许开发者将 UI 分解为可复用的组件。
  2. 直观的模板语法:JSX 结构类似于 HTML,这让开发者能够直观地描述 UI 结构,同时保持了与 JavaScript 的紧密集成,可以方便地在其中嵌入表达式和变量。
  3. 类型检查:当与 TypeScript 结合使用时,JSX 可以受益于类型检查,提高代码质量并减少运行时错误。
  4. 易于调试:转换后的 JavaScript 代码可以被开发者工具识别和调试,就像普通的 JavaScript 代码一样。
  5. 属性注入:JSX 允许开发者在标签中直接传入组件属性和子元素,方便地管理组件的状态和表现。

使用 JSX 的注意事项:

  • 在 JSX 中不能直接使用 JavaScript 表达式,需要包裹在 {} 中。
  • JSX 必须有一个顶层元素,不能返回多个不相关联的元素,除非将它们包裹在一个父元素中。
  • JSX 中的 className 属性对应 HTML 中的 class,for 属性对应 htmlFor,这是因为 JavaScript 关键字不能直接作为属性名使用。

总的来说,JSX 是 React 生态系统中不可或缺的一部分,它极大地简化了构建用户界面的过程,并促进了组件化开发的普及。

数据交换格式

JSON(JavaScript Object Notation)和XML(eXtensible Markup Language)都是用于数据交换的格式,它们各自有独特的结构和用途。

JSON:

  1. 起源与结构:JSON诞生于JavaScript语言,但现在已经成为了独立的数据格式标准,广泛应用于Web服务、API接口、客户端与服务器之间的数据交换。JSON数据采用键值对的形式,键和字符串值之间用冒号(:)分隔,键值对之间用逗号(,)分隔,整个对象用花括号({})包围。JSON还支持数组结构,数组元素之间用逗号(,)分隔,整个数组用方括号([])包围。

    示例:

    Json
    {
        "name": "John",
        "age": 30,
        "city": "New York",
        "interests": ["Reading", "Coding", "Guitar"]
    }
    
  2. 语法特点:JSON语法简洁、轻量,容易被人类和机器解析和生成。它的值可以是字符串、数字、布尔值、null、数组或另一个JSON对象。JSON不支持注释,且字符串和键必须用双引号(")包围。

  3. 解析与兼容性:JSON在JavaScript中拥有内置的解析和生成函数,如JSON.parse()JSON.stringify(),许多其他编程语言也支持JSON处理。由于其与JavaScript的天然亲和性,JSON在Web开发中尤为流行。

XML:

  1. 起源与结构:XML是一种可扩展的标记语言,1996年由W3C发布,设计之初主要用于描述数据和文档结构。XML文档由标签构成,标签可以自定义,并且可以嵌套,每个标签都有开始标签和结束标签(或者使用自闭合标签)。

    示例:

    Xml
    <person>
      <name>John</name>
      <age>30</age>
      <city>New York</city>
      <interests>
        <interest>Reading</interest>
        <interest>Coding</interest>
        <interest>Guitar</interest>
      </interests>
    </person>
    
  2. 语法特点:XML语法严谨,每个标签都需要正确闭合,标签名称区分大小写。XML允许自定义标签,每个标签可以有自己的属性。XML支持注释、CDATA区段以及文档类型声明(DTD)等高级特性,结构更为灵活和复杂。

  3. 解析与兼容性:XML需要专用的解析器进行解析,许多编程语言都提供了XML处理库。XML广泛应用于Web服务(如SOAP协议)、配置文件、数据交换等领域,尤其在需要严格的文档结构和数据验证时更具优势。

总结来说,JSON和XML各有优劣:

  • JSON格式简洁、易于阅读和编写,更适合于数据交换和Web应用;
  • XML提供了更强大的文档描述能力和结构扩展性,适合于复杂文档结构和需要严格数据验证的场景。在实际应用中,开发者会根据具体需求和项目环境选择合适的数据交换格式。

Fetch API

Fetch API 是现代浏览器中用于发出HTTP请求的一个标准化接口,它旨在替代传统的XMLHttpRequest(XHR)API,提供一个更简洁、更强大且基于Promise的网络请求接口。Fetch API 支持各种HTTP方法(GET、POST、PUT、DELETE等),并且适用于现代浏览器和Node.js环境(借助polyfill)。

Fetch API 的基本使用

Javascript
fetch(url[, options])

这里的 url 是你要请求的资源地址,而 options 是一个可选的配置对象,用于定义请求的各种属性,例如请求方法、请求头、请求体、以及是否发送credentials等。

示例

Javascript
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json(); // 如果响应体是JSON格式,转化为JavaScript对象
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('There has been a problem with your fetch operation:', error);
  });

Fetch API 的主要特点和方法

  • 返回Promise:fetch()方法返回一个Promise,该Promise在请求完成时解析为Response对象。
  • Response对象:Response对象包含了服务器的响应信息,如状态码、headers、body等。可以通过.json().text().blob()等方法解析响应体。
  • 请求配置:options 参数可以包含method(请求方法)、headers(请求头)、body(请求体)、mode(请求模式,如cors、no-cors等)、credentials(是否携带cookies和HTTP认证信息)、cache(缓存策略)等属性。
  • 错误处理:Fetch API的错误处理依赖于Promise的catch方法,需要注意的是,即使网络请求成功,也需要检查response.ok属性来判断HTTP状态码是否在200-299范围内,否则应抛出错误。
  • CORS支持:Fetch API内置了对CORS的支持,通过设置正确的请求头和模式可以实现跨域请求。
  • 自定义请求:可以通过new Request()构造函数创建自定义请求,然后传递给fetch()。

尽管Fetch API提供了更现代化的网络请求方式,但值得注意的是,相比于旧的XMLHttpRequest,fetch()在请求错误处理上可能稍显复杂,因为它对网络错误和HTTP错误的处理不那么直观。此外,fetch()对于不支持Promise的老旧浏览器需要额外的polyfill支持。

懒加载与预加载

懒加载(Lazy Loading)和预加载(Preloading)是两种用于优化网页或应用性能、减少资源消耗的加载策略,它们的目的都是为了提高用户体验,但实现方式和应用场景有所不同。

懒加载(Lazy Loading)

懒加载是一种按需加载资源的技术,主要用于改善页面性能,尤其是对于含有大量图片、视频或其他资源的长页面。当页面初次加载时,懒加载技术并不会加载所有可见区域之外的内容,而是在用户滚动到相关内容附近时才开始加载。这样做可以显著减少页面首次加载时的带宽消耗,提升页面加载速度,进而提高用户体验。

例如,在网页中,懒加载技术常用于图片资源,只有当图片进入浏览器视窗(viewport)或即将进入视窗时才发起图片请求。JavaScript可以通过监听滚动事件和计算元素在视窗的位置来实现图片的懒加载。

预加载(Preloading)

预加载则是提前加载预期用户在未来可能需要的资源。它会在浏览器空闲时提前加载资源,确保用户在真正需要这些资源时能够快速获取,从而减少用户交互时的等待时间。预加载常用于关键资源,比如即将跳转到的新页面的主要CSS和JavaScript文件,或者用户可能很快会点击的链接所指向的资源。

例如,网页可以在加载当前页面时就开始预加载下一个页面的资源,或者预加载即将展示的富媒体内容。HTML中可以通过<link rel="preload">标签来指示浏览器预加载指定资源。

总结来说,懒加载的核心在于推迟非即时需要资源的加载,减轻初次加载压力;而预加载则是主动预测和提前加载未来可能需要的资源,确保用户在实际需要时资源已经就绪,两者都是为了提高页面性能和用户体验。

Prefetch 是一种现代浏览器提供的资源加载策略,用来预先加载预期将来可能需要的资源,以提高用户浏览体验。通过 <link rel="prefetch"> 标签,开发者可以指示浏览器在后台悄悄地下载指定资源,而不需要立即执行或解析这些资源。等到用户真的导航到相关页面或请求相关资源时,由于资源已经被预加载,所以能够更快地加载页面或执行下一步操作。

例如,在HTML文档中可以这样使用prefetch预加载资源:

Html
<link rel="prefetch" href="/styles/lazy-loaded.css">
<link rel="prefetch" href="/images/large-cover.jpg">

当浏览器处于空闲状态时,会自动下载这些资源。但是要注意,预加载的资源不会被执行或应用,只是被浏览器缓存起来,等待未来的实际请求。Prefetch特别适用于那些预测用户下一步行动的场景,比如预加载下一页的CSS和JavaScript文件,或者用户可能滚动到的图片资源。

这种技术可以帮助减少用户等待时间和延迟感,特别是在资源较大或网络状况不佳的情况下,有助于提升网站的响应速度和整体性能。不过,应当谨慎使用,避免不必要的带宽消耗和缓存浪费。

<link rel="prefetch"> 和 <link rel="preload"> 都是用来提示浏览器提前加载资源的机制,但它们的用途和优先级有所不同:

  1. <link rel="prefetch">

    • 主要用于预加载未来可能需要的资源,通常在浏览器空闲时段进行,加载速度相对较慢,优先级较低。
    • 目标是提前将资源放入浏览器的缓存中,当用户随后访问相关页面或触发相关操作时,可以从缓存中快速获取资源,提高用户体验。
    • Prefetch适合用于预加载后续页面可能需要的资源,例如下一页的CSS或JavaScript文件。
  2. <link rel="preload">

    • 用于明确指示浏览器优先加载指定资源,与当前页面或后续页面的加载高度相关,具有较高的优先级。
    • Preload不仅将资源加载到缓存中,还会尽快开始下载并准备解析资源,以确保当资源实际需要时能够立即可用。
    • 通常用于关键资源的加载,例如当前页面的重要脚本、CSS文件、字体或即将播放的视频等。

总结来说,prefetch更多的是对未来可能用到资源的试探性加载,而preload则是强制且优先级高的预加载,用于关键资源的加速呈现。在实际应用中,开发者应根据资源的重要性和用户使用场景合理选择预加载策略。

防抖与节流

防抖(Debouncing)与节流(Throttling)是两种在JavaScript中用于优化频繁触发事件的处理策略,它们都是为了减少过度频繁的函数调用,提高性能和用户体验。

防抖(Debouncing)

防抖的原理是当事件被连续触发时,只有在最后一次触发后的一段时间内没有再次触发时,才执行函数。形象地说,就像一个开关,你连续按下去,但是在最后一次按下到松开这段时间内没有再次按下,开关才真正生效。防抖常常用于处理那些用户短时间内连续触发但只需要执行一次的情况,如输入框的搜索建议、窗口的resize事件等。

例如,实现一个防抖函数,确保用户停止输入500毫秒后才执行查询操作:

Javascript
function debounce(func, wait) {
  let timeoutId;
  return function(...args) {
    if (timeoutId) clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}

inputElement.addEventListener('input', debounce(search, 500));

节流(Throttling)

节流则是限制在一定时间内,无论事件如何连续触发,函数都只会按照固定的频率执行。例如,每秒钟最多执行一次,无论在这1秒内事件触发了多少次。节流可以保证函数执行的频率不会过高,同时保证最少每隔一定时间就会执行一次。

例如,实现一个节流函数,确保滚动事件每500毫秒最多执行一次:

Javascript
function throttle(func, wait) {
  let previousCall = 0;
  return function(...args) {
    const now = Date.now();
    if (now - previousCall >= wait) {
      func.apply(this, args);
      previousCall = now;
    }
  };
}

window.addEventListener('scroll', throttle(handleScroll, 500));

总结来说,防抖主要用于保证在短时间内连续触发的动作只执行最后一次,而节流则是限制函数执行频率,确保动作虽连续但执行次数受限。在实际应用中,选择哪种策略取决于具体的需求场景。

MVVM

MVVM(Model-View-ViewModel)是一种软件架构设计模式,特别是在前端开发中广泛应用于构建用户界面和管理数据绑定关系。该模式起源于微软WPF和Silverlight技术,并在现代前端框架(如AngularJS、Vue.js和KnockoutJS)中得到了广泛应用。

在MVVM架构中:

  • Model(模型层) :负责封装应用程序的数据和业务逻辑。模型可以与后端服务进行交互,获取或更新数据,并反映应用的状态。
  • View(视图层) :是用户界面的表现形式,它展示模型中的数据,但并不直接与模型交互。视图是由HTML(或模板)组成的,只负责展现数据,不关心数据如何改变。
  • ViewModel(视图模型层) :作为Model和View之间的桥梁,负责把模型中的数据转换成视图可以绑定和展示的形式,并将视图中的交互操作映射到模型的业务逻辑上。ViewModel观察模型数据的变化并自动更新视图,同时处理视图触发的事件并将数据变更传播到模型层。

简而言之,MVVM通过双向数据绑定技术,使得视图层与业务逻辑层分离,简化了界面与数据之间的耦合度,使开发人员能够专注于业务逻辑的编写,同时增强了界面的动态响应能力和可维护性。

持续集成/持续部署

持续集成/持续部署(CI/CD,Continuous Integration / Continuous Deployment)是一种自动化软件开发流程,用于确保代码在提交后迅速进行构建、测试、打包、部署等环节,从而缩短反馈周期,提高软件质量和可靠性。下面是如何在前端项目中实现CI/CD的基本步骤:

持续集成(CI)

  1. 版本控制系统(Git)

    • 使用Git等版本控制系统管理代码,确保每一次代码更改都有版本记录。
  2. 代码仓库托管服务

    • 将代码托管在GitHub、GitLab、Bitbucket等服务上。
  3. 设置CI服务

    • 注册并配置CI服务,如Travis CI、CircleCI、Jenkins、GitHub Actions或GitLab CI/CD等。
  4. 编写配置文件

    • 编写CI服务所需的配置文件(如.travis.yml、.circleci/config.yml等),定义构建和测试流程。
  5. 构建脚本

    • 创建自动化构建脚本(如package.json的scripts部分或单独的shell/bash脚本),包括编译、打包、linting、单元测试等步骤。
  6. 自动触发构建

    • 当开发者将代码push到特定分支时,CI服务自动触发构建过程。
  7. 构建状态通知

    • 构建结束后,CI服务通过邮件、Slack或Webhook等方式通知团队构建结果。

持续部署(CD)

  1. 自动化测试

    • 在CI流程中包含自动化测试,确保代码变更不会破坏现有功能。
  2. 环境隔离

    • 分别配置开发、测试、 staging 和生产环境,每个环境有不同的部署目标。
  3. 打包与版本管理

    • 使用构建工具(如Webpack、Rollup)将前端代码打包成适合部署的静态资源。
  4. 部署脚本

    • 创建自动化部署脚本,通过SSH、FTP、SCP或云服务商提供的API(如AWS CodeDeploy、Azure Release Pipelines等)将构建产物部署到相应环境。
  5. CD管道

    • 设置CD流程,将成功通过CI测试的构建成果自动部署到下一个环境(如从测试环境到staging环境,再从staging环境到生产环境)。
  6. 蓝绿部署/金丝雀发布

    • 根据项目规模和需求,可以采用蓝绿部署、金丝雀发布等策略,确保部署过程不影响线上服务。
  7. 权限与审批

    • 对于生产环境,可以设置必要的审批流程,在代码合并和部署到生产前进行人工审核。

通过以上步骤,前端项目可以实现持续集成和持续部署,从而促进团队高效协作,确保代码的质量和上线速度。

web安全

常见的加密方式

  1. 对称加密算法

    • DES (Data Encryption Standard) :早期的数据加密标准,现在由于密钥长度较短,已逐渐被淘汰。
    • 3DES (Triple DES) :DES的增强版,通过三次DES加密来提高安全性。
    • AES (Advanced Encryption Standard) :当前广泛使用的对称加密标准,提供了更好的性能和安全性,密钥长度有128位、192位和256位三种规格。
    • Blowfish、RC2、RC4、RC5、IDEA:这些都是其他曾经或仍在某些场景下使用的对称加密算法。
  2. 非对称加密算法

    • RSA:最为广泛使用的非对称加密算法,常用于密钥交换、数字签名等场景。
    • Elgamal:也是一种公钥加密算法,不过不如RSA应用得那么普遍。
    • ECC (Elliptic Curve Cryptography) :椭圆曲线密码学,相比RSA在相同的安全等级下所需密钥长度较小,因此更适合资源受限的设备。
    • Diffie-Hellman Key Exchange(DHKE):用于安全地在不安全的信道上协商共享密钥。
  3. 哈希算法

    • MD5:虽然已知存在碰撞问题,但因其速度快,仍偶尔用于简单数据完整性校验。
    • SHA-1:安全性较低,但仍有少量使用场景,已被更安全的SHA-2系列取代。
    • SHA-256、SHA-384、SHA-512:SHA-2系列的安全性较高,被广泛用于消息摘要、数字签名、密码哈希等场景。
    • bcrypt、scrypt:专门设计用于密码哈希的算法,增加了抗暴力破解的能力。
  4. 消息认证码(MAC)与HMAC

    • HMAC:基于哈希函数和密钥的认证码,用于确保消息完整性和真实性。
  5. 数字签名算法

    • RSA签名:使用RSA非对称加密算法实现数字签名。
    • ECDSA:基于椭圆曲线的数字签名算法,相较于RSA签名在同等安全级别下,能够使用更短的密钥。
  6. TLS/SSL

    • TLS(Transport Layer Security) :前身是SSL(Secure Sockets Layer),用于加密网络通信,如HTTPS,结合了对称加密、非对称加密、哈希算法等多种加密技术。
  7. WebCrypto API

    • 现代浏览器提供的Web Crypto API,允许JavaScript在浏览器端执行加密操作,支持多种加密、解密、哈希、签名等操作。
  8. 其他加密技术

    • Web Storage加密:如Local Storage、Session Storage中的数据加密。
    • Web Workers加密:在Web Workers中进行加密运算以避免阻塞主线程。
    • Web Cryptography API:提供了更多现代加密算法和操作,如AES-GCM、HKDF等。

以上提及的加密方式只是众多加密技术中的一部分,每种加密技术都有其适用场景和安全考量。在实际应用中,根据需求和安全等级选择合适的加密算法和方案至关重要。

Web爬虫

Web爬虫(Web Crawler),又称网页爬虫、网络爬虫或蜘蛛(Spider)、机器人(Robot),是一种自动在网络上爬取和抓取网页信息的程序。它依据预设的规则,沿着网页中的超链接从一个网页爬行到另一个网页,持续不断地抓取网页内容,并对其进行分析和存储。

Web爬虫的工作原理通常包括以下步骤:

  1. 初始化:爬虫从种子URL(通常是用户指定的起始网址)开始启动。
  2. 下载网页:通过HTTP(S)协议向服务器发送请求,下载网页HTML内容或其他格式的数据。
  3. 解析内容:下载后的网页内容通过HTML解析器解析,提取出其中的超链接和其他感兴趣的信息,如文本、图片、视频等。
  4. 数据抽取:根据预先设定的规则,抽取有用的数据并进行清洗、整理。
  5. 去重:为了避免重复抓取相同的网页内容,爬虫会使用URL去重策略,如布隆过滤器(Bloom Filter)或集合存储已抓取过的URL。
  6. 跟踪链接:从当前网页中提取出新的链接,并将它们加入待抓取队列,继续遍历和抓取网页。
  7. 数据存储:将抓取到的数据存储在本地数据库、文件或云端存储系统中,以便后续分析或使用。

Web爬虫的应用广泛,包括但不限于:

  • 搜索引擎构建:搜索引擎通过大规模爬虫抓取互联网上的网页内容,并建立索引供用户搜索。
  • 市场调研:用于收集竞争对手的产品信息、价格变动等商业情报。
  • 大数据分析:获取大量数据用于科学研究、社会调查、舆情分析等领域。
  • 内容聚合:新闻聚合、社交媒体监测等应用需要定期抓取目标网站的内容更新。

值得注意的是,在使用Web爬虫时,必须遵守法律法规,尊重网站的Robots协议(robots.txt),合理安排爬取频率,避免给目标服务器带来过大负担,同时保护用户隐私和个人数据安全。否则可能会触犯法律或道德规范。

浏览器安全

同源策略

浏览器同源策略(Same-Origin Policy, SOP)是浏览器为保证用户信息安全和阻止恶意行为而实施的一种核心安全策略。同源策略规定了来自同一来源(协议、域名和端口均相同)的文档、脚本或样式表之间可以自由交互,而不同源的资源则有着严格的访问限制。

白帽黑客在讨论Web安全时,会强调同源策略在浏览器安全中的重要作用,因为它主要体现在以下几个方面:

  1. 数据隔离

    • 同源策略禁止一个网页通过脚本(如JavaScript)直接访问或修改另一个不同源网页的DOM结构和cookie等数据,除非该网页显式设置了CORS(跨源资源共享)策略允许特定源的访问。
  2. 防止恶意注入

    • 同源策略防止恶意网站通过iframe、script标签等方式嵌入其他网站的内容,并试图从中窃取或篡改数据,降低了XSS(跨站脚本攻击)和CSRF(跨站请求伪造)等攻击的风险。
  3. 资源加载限制

    • 不同源的图片、样式表和脚本等资源可以被加载,但脚本不能读取这些资源的内容,除非资源明确设置了Access-Control-Allow-Origin头部允许跨域访问。
  4. API访问控制

    • 许多浏览器提供的API(如LocalStorage、IndexedDB、Cookies、XMLHttpRequest、Fetch等)也都遵循同源策略,限制了不同源之间对这些API数据的读写访问。

在实践中,白帽黑客会在评估Web应用安全性时关注同源策略的正确实施,以及如何利用现有的安全机制(如CORS、Content Security Policy等)来强化同源策略的限制,以防止因同源策略漏洞引发的安全风险。同时,他们也会研究绕过同源策略的攻击技术和防御措施,帮助开发者更好地理解并修复这类潜在的安全隐患。

CORS

CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种W3C标准,用于解决不同域之间AJAX请求的问题。在同源策略的限制下,出于安全原因,浏览器默认不允许脚本(如JavaScript)发起跨域请求。然而,通过CORS机制,服务器可以选择允许来自其他源的请求。

CORS的工作原理基于HTTP头信息,主要包括以下几个关键步骤和配置项:

  1. 预检请求(Preflight Request) : 当请求方法不是GET、HEAD或POST,或者请求头中包含如自定义头、Content-Type(非application/x-www-form-urlencoded、multipart/form-data、text/plain)等非简单请求特征时,浏览器会首先发送一个OPTIONS预检请求到服务器,询问服务器是否接受真实的请求。预检请求中包含以下重要的头信息:

    • Origin:发送请求的源(浏览器当前页面所在的域名和端口)。
    • Access-Control-Request-Method:即将发送的请求方法(如PUT、DELETE等)。
    • Access-Control-Request-Headers(可选):即将发送的自定义请求头。
  2. 服务器响应预检请求: 服务器根据预检请求返回一个响应,其中包含允许的跨域策略:

    • Access-Control-Allow-Origin:指定允许跨域访问的源,可以用通配符*表示允许任何源,也可以明确指定源。
    • Access-Control-Allow-Methods:列出允许的方法,如GET、POST、PUT、DELETE等。
    • Access-Control-Allow-Headers(可选):允许客户端发送的自定义头信息。
    • Access-Control-Max-Age(可选):预检请求结果的缓存时间,减少后续请求的预检次数。
    • Access-Control-Allow-Credentials(可选):如果设为true,表示允许携带cookies或HTTP认证信息进行跨域请求。
  3. 实际请求与响应: 如果预检请求成功,浏览器将发起实际的请求,服务器在响应头中同样需要返回Access-Control-Allow-Origin等信息。若请求方法为简单请求,一般情况下浏览器直接发起请求,服务器响应时同样需要包含Access-Control-Allow-Origin等头信息。

配置CORS通常是在服务器端进行,例如在Node.js的Express框架中,可以使用cors中间件来实现:

Javascript
var express = require('express');
var cors = require('cors');

var app = express();
app.use(cors({
  origin: ['http://example.com', 'http://other-site.com'], // 允许的源列表
  credentials: true, // 是否允许携带凭证(如cookies)
  methods: ['GET', 'POST', 'PUT', 'DELETE'], // 允许的方法
  allowedHeaders: ['Content-Type', 'Authorization'], // 允许的自定义头信息
0}));

app.get('/api/data', function(req, res) {
  // 处理请求...
  res.json({ some: 'data' });
});

app.listen(3000);

通过正确的CORS配置,服务器就能够接受并响应来自不同源的请求,实现跨域资源共享。

其它解决跨域问题的方案

除了CORS(Cross-Origin Resource Sharing)这一主流跨域解决方案之外,还有其他几种方式可以解决或规避跨域问题,具体如下:

  1. JSONP (JSON with Padding) : JSONP是一种非正式的跨域数据交互协议,利用 <script> 标签不受同源策略限制的特性,通过动态插入一个src属性指向跨域资源的script标签,服务端返回一个调用预先定义好的回调函数并将JSON数据作为参数的方式实现跨域通信。JSONP只支持GET请求,不支持POST等其他HTTP方法,且存在安全隐患,现在已被CORS逐渐取代。

  2. CORS的降级方案:代理服务器

    • Nginx代理:在服务器端配置Nginx反向代理,将跨域请求转发到实际服务器,从而看起来像是同源请求。
    • API Gateway:通过API Gateway服务作为中间层,处理所有的API请求,Gateway本身可以处理跨域问题,使得客户端与服务器之间的通信被视为同域。
  3. WebSocket协议: WebSocket协议本身支持跨域,只需服务器端设置好相应的CORS响应头,即可实现跨域通信。WebSocket提供长连接,适合实时通信场景。

  4. 图片ping(Image Ping / JSONP via Image) : 利用 <img> 标签请求图片资源不受同源策略限制的特性,通过改变请求的查询参数来传递数据,然后通过服务器端解析请求参数实现跨域通信。这种方式只能获取数据,无法发送数据,且数据类型受限。

  5. POSTMessage API: 在IFrame场景下,可以通过window.postMessage方法在同源或跨域的窗口之间传递消息,实现父子窗口间的通信。

  6. WebRTC (Web Real-Time Communication) : WebRTC提供浏览器之间直接音视频通话和数据分享的能力,也支持跨域数据交换。

  7. document.domain设置: 当两个页面的域名二级域名相同的情况下,可以通过设置document.domain属性来实现跨子域通信。

  8. Location.hash / window.name: 利用location.hash和window.name属性进行跨域数据传递,不过这种方式功能有限且实现复杂。

总的来说,CORS是目前最常用和最规范的跨域解决方案,其他方案往往在特定场景下使用,或者作为CORS的补充手段。在设计系统时,应当首选CORS,并在不支持CORS的旧版浏览器中寻找适当的降级方案。

浏览器沙箱

浏览器沙箱(Browser Sandbox)是一种安全技术,它在浏览器内部创建了一个隔离的执行环境,使得在该环境中运行的网页内容(尤其是JavaScript脚本)无法直接访问或修改主机系统的底层资源,如文件系统、操作系统核心、硬件设备等。通过沙箱机制,浏览器确保了即便网页中包含恶意代码或存在安全漏洞,也不会对用户的计算机系统造成严重的损害。

浏览器沙箱的核心工作原理如下:

  1. 进程隔离:现代浏览器如Google Chrome和Mozilla Firefox通常为每一个网页标签页或iframe创建独立的进程,各个进程之间的内存和资源是相互隔离的。
  2. 权限限制:在沙箱内部运行的脚本仅被赋予有限的一组权限,例如只能访问有限的API,不允许直接进行文件操作或网络请求(除非用户明确授权或通过CORS等机制合法授权)。
  3. 安全边界:浏览器通过对系统调用级别的控制,限制了沙箱内代码访问非授权资源的能力,即便代码试图执行危险操作,也会被浏览器的安全机制拦截或忽略。
  4. 内存管理:浏览器对分配给沙箱环境的内存进行严格管理,一旦沙箱进程结束,其所占用的内存将被回收,避免持久化恶意代码或泄露用户数据。

通过这样的机制,浏览器沙箱有效地减少了因网页中潜在恶意代码而导致的安全风险,增强了用户浏览网页的安全性。

XSS

XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的Web应用程序安全漏洞,它允许攻击者在受害者浏览器中注入恶意脚本,这些脚本在用户浏览网页时被执行,可能导致诸如账户劫持、隐私数据泄露、恶意操作用户账号、重定向到恶意网站等各种安全问题。

XSS攻击主要有三种类型:

  1. 反射型XSS(Reflected XSS)

    • 攻击者通过构造带有恶意脚本的URL,诱导受害者点击。当服务器接收到请求后,未经过滤直接将攻击脚本回显在响应页面中,导致受害者的浏览器执行了这段脚本。
  2. 存储型XSS(Stored XSS)

    • 攻击者将恶意脚本提交到Web应用的数据库中,例如在论坛、博客评论区等地方发布包含恶意脚本的内容。当其他用户查看含有恶意脚本的内容时,他们的浏览器会执行这段脚本。
  3. DOM-Based XSS(基于DOM的XSS)

    • 这种类型的XSS并不依赖服务器回显数据,而是由于客户端JavaScript代码在处理来自不可信源的数据时未能妥善过滤或转义,直接将数据插入到网页的DOM(文档对象模型)中,导致恶意脚本被执行。

预防XSS攻击的主要措施包括:

  • 输入验证和净化:对用户提交的所有数据进行严格的过滤和转义,确保输出到页面时不会构成有效的JavaScript代码。
  • HTTP响应头设置:使用HTTP响应头如Content-Security-Policy(CSP)来限制脚本的来源,只允许执行信任源的脚本。
  • 输出编码:在向浏览器输出数据时,确保对特殊字符进行适当的HTML实体编码,防止被解释为HTML或JavaScript代码。
  • 安全编程实践:在处理DOM时,确保对来自不可信源的数据进行清理或使用安全的API方法插入到DOM中。

总之,XSS攻击是对用户数据和隐私安全的巨大威胁,Web应用程序开发者应时刻关注并采取措施防止此类漏洞的发生。

CSRF

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种网络攻击手段,攻击者利用网站对用户Cookie或其他认证信息的信任,诱使已登录用户在不知情的情况下执行非本意的操作,从而达到攻击目的。

攻击原理:

  1. 用户A在浏览器中登录了某网站,并获得了该网站的Cookie(或者其他认证信息)用于标识身份。
  2. 攻击者B构建一个恶意网页,其中包含一个针对该网站的请求(比如转账、发表文章、修改密码等),并将这个请求伪装成正常请求,如通过隐藏的表单提交或者Ajax请求。
  3. 当用户A在不知情的情况下访问了攻击者B构造的恶意网页时,浏览器会自动带上用户A在该网站上的有效Cookie和其他认证信息发起请求。
  4. 由于服务器收到的请求带有合法用户的认证信息,于是误以为是用户A自主发起的请求,进而执行了请求中的操作。

防御CSRF的方法包括但不限于:

  • Token验证:服务器在发出表单提交页面时生成一个随机的、一次性的token,提交时需验证这个token,以证明请求是来源于服务器认可的页面而非伪造。
  • 双重Cookie验证:除了Session Cookie,服务器还可以设置一个专门用于CSRF防护的Cookie,不包含敏感信息且设置HttpOnly标志防止JS读取,服务器在处理敏感操作时检查两者是否匹配。
  • POST请求验证:仅允许敏感操作通过POST方法发起,并尽量避免GET方法执行敏感操作,因为GET请求容易被嵌入到链接或图片标签中。
  • 检查Referer头:虽然不是非常可靠,但在某些场景下,服务器可以通过检查HTTP请求头中的Referer来判断请求是否来自正确的源站。

综合使用多种防御手段可以大大提高网站抵抗CSRF攻击的能力。

HTML

盒模型

盒模型(Box Model)是CSS(层叠样式表)中用于定义网页元素布局和尺寸的核心概念。在HTML文档中,每个元素都被视为一个矩形的盒子,这个盒子由以下几个部分组成:

  1. 内容区域(Content) :这是元素的主体部分,它包含了元素的实际内容,如文本、图像、视频等。设置widthheight属性时,按照标准盒模型,这两个值仅影响内容区域的大小。
  2. 内边距(Padding) :围绕内容区域四周的是内边距,它为内容区域提供了空白空间。可以通过padding-toppadding-rightpadding-bottompadding-left属性来设置各边的内边距大小。内边距是透明的,不影响背景颜色的渲染。
  3. 边框(Border) :紧接着内边距的是边框,边框可以有宽度、样式(实线、虚线等)和颜色属性,分别通过border-widthborder-styleborder-color设置。
  4. 外边距(Margin) :最外面是外边距,它定义了元素与其他元素之间的距离,确保了元素间的间距。外边距是透明的,也不影响背景颜色。可以通过margin-topmargin-rightmargin-bottommargin-left属性设置各个方向的外边距。

关于盒模型有两种主要计算方式:

  • 标准盒模型(W3C Box Model) :当声明元素的widthheight时,这些值仅仅应用于内容区域。内边距和边框不会增加元素的整体宽度和高度。
  • IE盒模型(Quirks Mode 或怪异盒模型) :在一些老版本的IE浏览器中,默认的盒模型行为是将widthheight属性包括了内容、内边距和边框。为了统一不同浏览器的行为,CSS3引入了box-sizing属性,通过设置box-sizing: border-box;可以使元素遵循IE盒模型的计算方式,即包括内边距和边框在内的尺寸才是元素的总宽高。而在默认的标准盒模型下,box-sizing: content-box;表示宽度和高度不包括内边距和边框。

浏览器多标签页之间的通信方式

juejin.cn/post/700201…

浏览器多标签页之间的通信主要有以下几种方式:

  1. LocalStorage/SessionStorage

    • localStoragesessionStorage是HTML5提供的Web Storage API,它们提供了持久化存储机制,数据在同一域名下的不同标签页间可以共享。当一个标签页对localStoragesessionStorage进行读写操作时,将会触发storage事件,其他同源标签页可以通过监听这个事件来接收通知并作出相应反应。
  2. Cookies

    • Cookies虽然主要用于身份验证和跟踪用户状态,但也可以作为浏览器各个标签页间共享信息的一种方式。不过,由于其大小限制、安全性以及每次HTTP请求都会携带的特性,通常不推荐用于大量数据或者实时通信。
  3. WebSockets

    • 使用WebSocket协议可以建立浏览器与服务器间的双向通信通道。各个标签页可以通过各自连接到同一个WebSocket服务器,并通过服务器中转消息来间接实现彼此之间的通信。
  4. Shared Workers

    • Shared Worker是一种浏览器内置的工作线程,它可以被多个浏览器标签页共享,这样就可以通过共享的Worker进程作为中介,在不同的标签页间传递消息。
  5. Broadcast Channel API

    • HTML5引入的Broadcast Channel API允许来自同一源的不同上下文(比如不同标签页、窗口、iframe)之间创建一个简单的通信信道,通过它可以直接发送和接收消息。
  6. PostMessage API

    • 虽然PostMessage API主要用于跨窗口(包括跨域窗口)的消息传递,但在某些场景下也可用于同一站点内的多标签页通信,例如通过消息中心或其他类型的内部消息队列机制。

总结来说,对于多标签页通信,最常用的手段可能是localStorage配合storage事件,以及利用现代浏览器提供的更直接的通信接口如Broadcast Channel API。如果是需要实时性较高或复杂的数据交换,则可能倾向于选择WebSocket这种网络层的解决方案。

HTML5本地存储方案

HTML5为网页应用提供了多种本地存储方案,主要包括以下几种:

  1. localStorage

    • localStorage是一个持久化存储,用于在用户浏览器端存储大量数据(约5MB左右)。数据存储在本地,直到被明确删除或达到存储限制为止,即使浏览器关闭后重新打开,数据仍然存在。数据是以键值对(key-value pairs)的形式存储的,适合长期保存用户设置、应用数据等。
  2. sessionStorage

    • sessionStorage与localStorage相似,也是以键值对形式存储数据,但它只在当前浏览器会话中有效。一旦浏览器窗口或标签页关闭,sessionStorage中的数据就会被清除。这对于保存临时会话状态或临时用户输入非常有用。
  3. IndexedDB

    • IndexedDB是一个更高级的客户端数据库,允许存储大量结构化数据,支持索引和查询。相比于localStorage,IndexedDB提供了更复杂的数据模型和更大的存储容量,适合存储大量结构化数据,如离线应用的数据缓存。
  4. Web SQL Database

    • Web SQL Database曾是一个W3C草案,现已不再推荐使用,但在一些老旧浏览器中仍能得到支持。它是一个嵌入到浏览器中的SQLite数据库,允许执行SQL查询来操作存储的数据。
  5. Cache API (Service Worker)

    • 与上述存储方案不同,Cache API主要用于离线缓存,是PWA(Progressive Web Apps)的关键技术之一。通过Service Worker,开发者可以预先缓存静态资源,使得在离线环境下也能提供部分功能和服务。
  6. File System API(已废弃)

    • File System API最初是为了允许网页应用程序直接访问用户的本地文件系统,但由于隐私和安全方面的担忧,大部分浏览器已经停止支持此API。

综上所述,HTML5本地存储方案主要是localStorage、sessionStorage和IndexedDB,以及其他辅助存储技术,如Service Worker配合Cache API,它们共同增强了Web应用程序的离线能力和本地数据处理能力。

WebWorker

Web Worker是HTML5引入的一项技术,它允许JavaScript在浏览器后台独立于主线程(UI线程)运行脚本,从而能够执行一些计算密集型、长时间运行的任务,而不会阻塞主线程,保证用户界面的流畅交互。

具体而言,Web Worker通过创建一个新的执行上下文(工作线程)来运行JavaScript代码,这个上下文与主线程相互独立,拥有自己的事件循环。Web Worker可以执行各种CPU密集型操作,例如大数据计算、文件读取或解析、复杂的算法执行等。它与主线程之间的通信是通过消息传递机制完成的,即通过postMessage()方法发送消息,然后在Worker线程和主线程之间通过onmessage事件监听和处理消息。

需要注意的是,Web Worker由于运行在独立线程中,无法直接访问DOM或修改网页内容,但可以访问部分全局对象,如navigatorlocation的部分只读属性,并且拥有自己独立的全局作用域,可以使用importScripts()方法导入外部脚本。

Web Worker有两种类型:

  • 常规Worker(Dedicated Worker) :为每个Worker创建一个独立的线程,一次只能处理一项任务。
  • 共享Worker(Shared Worker) :可以被多个浏览器上下文(例如多个标签页或窗口)共享,允许在多个上下文间共享数据和状态。

通过Web Worker技术,开发者可以有效地分离Web应用的计算密集型任务,改善用户体验,特别是在处理复杂逻辑时避免造成页面卡顿或无响应。

postMessage

juejin.cn/post/684490… postMessage是HTML5引入的一种跨文档消息传递(Cross-document messaging)API,它允许来自不同源(window、iframe或worker)的脚本在保证安全的前提下进行通信。通过postMessage方法,一个窗口可以向另一个窗口发送一条消息,接收到消息的窗口通过监听message事件来获取并处理这条消息。

基本用法:

  1. 发送消息:

    Javascript
    1// 在发送消息的窗口(或iframe、worker)中
    2otherWindow.postMessage(message, targetOrigin);
    

    其中:

    • message:要发送的数据,可以是任何类型,但会转换为字符串格式进行传递。
    • targetOrigin:指定消息可以发送到的源(协议、主机名、端口号),如果是"*",则不限制目标源,但这样做可能存在安全风险。
  2. 接收消息:

    Javascript
    1window.addEventListener('message', function(event) {
    2  if (event.origin === expectedOrigin) { // 校验发送消息的源是否可信
    3    var receivedMessage = event.data;
    4    // 在这里处理接收到的消息
    5  }
    6}, false);
    

    其中:

    • event.data:接收到的消息内容。
    • event.origin:发送消息窗口的源。

应用场景

  • 跨窗口(iframe间、弹窗与主页面间)通信。
  • 跨域资源共享(CORS)的补充,实现不同域名下的页面间数据交换。
  • Web Worker与主页面之间的数据交换。

postMessage方法极大地增强了网页间的交互能力,使得复杂多窗口或多源的应用场景得以实现,同时也加强了网页的安全性,只有在指定目标源的情况下,消息才能被正确接收和处理。

WebSocket

WebSocket是一种在单个TCP连接上进行全双工通信的协议,它允许客户端和服务器之间进行实时、双向的数据传输。WebSocket的设计目的是为了让Web应用程序能够实时推送数据,而不是传统的HTTP协议那样只有客户端发起请求,服务器才能响应。

WebSocket的工作原理如下:

  1. 初始化握手阶段:客户端通过升级HTTP协议,发送一个特殊的WebSocket请求到服务器,请求头中包含了升级协议的信息。服务器如果支持WebSocket,会同意这次协议升级,返回101 Switching Protocols状态码,并在Upgrade头部字段表明协议已升级为WebSocket。
  2. 建立连接后:连接成功建立之后,WebSocket的连接就保持着打开的状态,双方都可以随时向对方发送数据。数据帧以二进制格式传输,支持文本和二进制数据类型。
  3. 数据传输阶段:与HTTP不同,WebSocket连接一旦建立就不需要为每一次数据传输重新建立连接或发起请求,因此可以提供低延迟、实时的通讯服务。
  4. 断开连接:当一方想要断开连接时,可以通过发送特定的关闭帧来结束WebSocket连接。

WebSocket广泛应用于实时聊天、股票报价、游戏、协同编辑等需要实时双向通信的场景。在浏览器中,WebSocket API可以通过WebSocket构造函数实例化一个WebSocket对象,然后通过其方法进行连接、发送和接收数据。

File API

File API是HTML5引入的一组API,它允许Web应用程序访问用户计算机上的文件系统,从而实现上传文件、读取文件内容、展示文件信息等功能。File API主要包括以下几个核心组成部分:

  1. FileList对象: 当用户通过 <input type="file"> 控件选择文件后,可通过 files 属性获取一个FileList对象,该对象包含了用户所选的所有文件。
  2. File对象: 每个从FileList对象中获取的项都是一个File对象,它包含了文件的相关信息,如名称、大小、类型、修改日期等,并且可以通过FileReader接口读取文件内容。
  3. FileReader接口: FileReader接口提供了异步读取Blob或File对象的方法,可以用来读取用户设备上的文件内容。它支持的方法包括 readAsTextreadAsDataURLreadAsArrayBuffer 等,分别用于读取文本、Base64编码的数据URL和原始二进制数组。
  4. Blob对象: Blob对象代表不可变的、原始数据的类文件对象。它可以是用户上传的文件,也可以是JavaScript生成的数据。Blob可以被FileReader读取,也可以通过URL.createObjectURL()方法生成一个临时的URL用于引用这个Blob对象,以便在网页中显示或下载。
  5. FileWriter接口(部分浏览器支持): FileWriter接口提供了对用户文件系统进行读写操作的能力,允许Web应用向用户设备上指定的文件写入数据。但要注意的是,出于安全考虑,不是所有浏览器都支持FileWriter,而且这个接口的使用受到严格的权限限制。

File API极大地增强了Web应用程序对本地文件系统的访问能力,使得在线办公、文件处理、拖拽上传等多种涉及文件操作的功能得以实现。

videoaudio API

HTML5中的<video><audio>元素及其相应的JavaScript API为网页媒体播放带来了原生支持,消除了对Flash等插件的依赖。这些API允许开发者直接在浏览器中控制音频和视频内容,包括加载、播放、暂停、音量调整、播放进度控制以及其他高级功能。

以下是<video><audio>元素以及它们对应的API的一些主要特性:

Video API

  • <video>标签:用于在网页中嵌入视频内容。

    • 属性:

      • src: 指定视频文件源。
      • autoplay: 是否自动播放。
      • preload: 可以设置为nonemetadataauto,决定视频资源的预加载策略。
      • controls: 显示默认的播放控制条。
      • 更多属性,例如loop、muted、poster等。
    • JavaScript API:

      • currentTime: 获取或设置当前播放位置。
      • play(): 开始或恢复播放。
      • pause(): 暂停播放。
      • volume: 音量控制。
      • duration: 获取视频总时长。
      • ended事件:当视频播放结束时触发。
      • 还有许多其他事件和方法,如canPlayType()检测浏览器是否支持特定格式,addEventListener()用于监听播放状态变化等。

Audio API

  • <audio>标签:类似<video>标签,用于嵌入音频内容。

    • 同样具有上述大部分<video>标签的属性和方法。
  • JavaScript API同样适用于<audio>元素,包括控制播放、暂停、音量、播放位置等操作。

开发者可以根据需要通过这些API构建自定义的播放器界面和交互逻辑,同时兼容不同浏览器对于音频和视频格式的支持情况,可能需要提供多种格式的源文件以确保跨浏览器兼容性。

canvas

HTML5 <canvas> 元素是用于在网页上绘制图形的一种强大工具,它提供了一个可编程的绘图表面,允许开发人员使用JavaScript来动态生成图形和图像。<canvas> 元素本身不包含任何内容,但它定义了一个区域,开发者可以通过JavaScript API来绘制图形、制作动画、实现交互式效果等。

以下是 <canvas> 使用的基本步骤:

  1. 声明 canvas 元素: 在HTML文档中添加一个<canvas>元素,设置宽度和高度属性。

    Html
    <canvas id="myCanvas" width="500" height="500"></canvas>
    
  2. 获取 canvas 上下文: 通过JavaScript获取canvas元素,并创建绘图环境。主要有两种类型的上下文:“2d”(二维绘图)和“webgl”(三维WebGL绘图)。

    Javascript
    var canvas = document.getElementById('myCanvas');
    var ctx = canvas.getContext('2d'); // 获取2D绘图上下文
    // 或者
    var gl = canvas.getContext('webgl'); // 获取WebGL绘图上下文
    
  3. 绘图操作: 使用获取的上下文对象进行各种绘图操作,例如填充颜色、画线、画圆、绘制图像、添加文本等。

    Javascript
    ctx.fillStyle = 'rgb(200, 0, 0)';
    ctx.fillRect(10, 10, 150, 100); // 填充一个红色矩形
    
    ctx.beginPath();
    ctx.arc(95, 50, 40, 0, Math.PI * 2, true);
    ctx.fillStyle = 'green';
    ctx.fill(); // 画一个绿色圆形
    
  4. 高级功能: canvas API还支持更复杂的图形绘制,如贝塞尔曲线、渐变填充、阴影效果、图像合成等。对于WebGL,可以用来创建基于着色器的3D图形和场景。

通过HTML5 <canvas> 元素及其JavaScript API,开发者能够创造出丰富的视觉体验,从简单的图表到复杂的交互式游戏和数据可视化应用都可以实现。

canvas离屏渲染

Canvas离屏渲染是一种提高渲染效率的技术,主要是为了减少页面重绘的开销和提高性能。离屏渲染的核心思想是将复杂的绘图操作或者频繁更新的部分在一个不可见的Canvas(也称为离屏Canvas,即OffscreenCanvas)上完成,然后再一次性或按需将这个预渲染的结果复制到实际可见的Canvas上。

离屏Canvas (OffscreenCanvas)

  • OffscreenCanvas API允许在Web Worker线程中独立于主线程进行Canvas的渲染工作,从而释放主线程处理其他任务,尤其是对于CPU密集型的绘图操作或实时渲染场景,这能显著改善用户体验,防止因为长时间的渲染阻塞而导致的界面卡顿。
  • OffscreenCanvas对象可以直接在Worker线程中创建并使用,也可以从主线程上的普通Canvas元素通过transferControlToOffscreen()方法获得。

应用场景

  • 动态背景或复杂元素的预先绘制和复用。
  • 实时渲染,比如视频流的帧处理,或者是游戏中的复杂场景渲染。
  • 图形资源的预加载和缓存。
  • 高性能动画和特效的实现,特别是当它们不需要直接与用户交互时。

使用离屏渲染的一般步骤

  1. 创建一个OffscreenCanvas实例。
  2. 在OffscreenCanvas上进行所有的绘图操作。
  3. 完成绘制后,可以通过getImageData()toDataURL()获取像素数据,或者将OffscreenCanvas作为源通过drawImage()方法绘制到主Canvas上。

在WebGL中,离屏渲染还可以结合WebGLRenderTarget来实现,通过设置渲染目标为一个非默认帧缓冲区,从而达到类似的效果。

总之,离屏渲染有助于提升canvas图形性能的关键在于将耗时的渲染过程异步化和分隔化,从而减小对页面刷新率的影响,并且优化整体渲染流程。

CSS

CSS预处理器

CSS预处理器是一种特殊的工具,它为CSS代码提供了类似于编程语言的扩展特性,如变量、嵌套规则、混合(mixin)、函数运算、继承等。通过使用CSS预处理器,开发者能够以一种更加强大、灵活且易于维护的方式来编写CSS样式。

一些流行的CSS预处理器包括:

  1. Sass (Syntactically Awesome Stylesheets) :Sass是最先出现也是最广为人知的CSS预处理器之一,它提供了两种语法格式SCSS(Sassy CSS,与CSS语法相似,后缀名为.scss)和原有的缩进式语法(后缀名为.sass)。Sass引入了变量、嵌套、mixins、继承、运算符、函数等特性,极大地增强了CSS的表达能力和代码复用性。
  2. LESS (Leaner Style Sheets) :LESS同样具备变量、嵌套、混合、运算等功能,并且可以直接在CSS文件中通过@import语句导入LESS文件,逐步转换为CSS。LESS的语法与CSS更为接近,使得初学者更容易上手。
  3. Stylus:Stylus也是一种强大的CSS预处理器,以其灵活性和简洁的语法著称。它允许开发者选择是否使用括号和分号,同时提供变量、嵌套、混合、函数等特性,以及条件判断和循环等更高级的功能。

使用CSS预处理器的好处主要包括:

  • 可维护性:通过变量和函数的使用,减少了重复代码,使得样式的修改更加集中和方便。
  • 代码复用:通过mixins或extends功能,可以编写可重用的样式模块,减少冗余代码,提高代码质量。
  • 逻辑编程:支持条件语句和循环结构,能够根据条件生成不同的样式。
  • 模块化和组织结构:支持嵌套规则,使得CSS代码结构更加清晰,便于组织和阅读。

CSS预处理器编写的代码最终会被编译成常规的CSS代码,然后被浏览器识别和解析。这种方式为CSS赋予了更强的编程范式,使得前端开发更为高效和有序。

CSS Modules

CSS Modules 是一种前端开发技术,旨在解决全局CSS命名空间造成的样式冲突问题,并增强CSS在模块化开发环境中的可复用性和可维护性。CSS Modules 在CSS的基础上添加了局部作用域和模块导入导出的特性,使得每个CSS类名在每个模块中都是唯一的,从而避免了全局范围内的样式冲突。

在CSS Modules 中,开发人员可以编写普通的CSS文件,然后通过构建工具(如Webpack、Parcel等)将CSS文件与JavaScript模块关联起来。CSS Modules 会自动为CSS类名添加一个唯一哈希值,确保了在不同模块中使用相同类名时,生成的类名在全局是唯一的。

举例说明:

  1. 开发者编写一个名为Button.module.css的CSS Modules 文件:
Css
/* Button.module.css */
.button {
  color: blue;
  border: 1px solid black;
}

.active {
  background-color: lightgray;
}
  1. 在JavaScript模块中导入并使用CSS Modules:
Javascript
// Button.js
import styles from './Button.module.css';

function Button({ active }) {
  return (
    <button className={`${styles.button} ${active ? styles.active : ''}`}>
      Click me!
    </button>
  );
}

在编译后的HTML中,按钮元素的class会被替换为带有唯一哈希值的类名,例如:

Html
<button class="Button_button__xyz123 Button_active__abc456">Click me!</button>

CSS Modules 主要优势如下:

  • 避免样式冲突:通过为每个CSS类名生成独特的哈希标识,确保在项目中不会有类名冲突的问题。
  • 模块化:CSS与JavaScript模块紧密关联,可以像管理JS模块一样管理CSS样式。
  • 更好的复用:可以轻松地将样式封装到可复用的组件中,提高了代码的复用性和组织性。

通过CSS Modules,前端开发者可以享受到类似于JS模块的局部作用域带来的好处,使得大规模项目中的CSS代码更加可控和易于维护。

BFC

juejin.cn/post/684490…

区块格式化上下文(Block Formatting Context, BFC)是CSS布局模型中的一个概念,它定义了一个独立的渲染区域,内部的布局不受外部浮动元素的影响,并且遵循一套特定的渲染规则。BFC内的元素布局不会与BFC外部的元素相互重叠,而且可以包含浮动元素,清除浮动对周围元素的影响。

BFC的主要特性包括:

  1. 内部布局规则

    • BFC中的块级元素会在垂直方向上一个接一个放置。
    • 水平方向上,元素会尽量靠左或靠右放置,具体取决于书写模式。
    • 每个元素的左边缘(对于从左到右的书写模式)会紧贴包含块的左边,除非遇到浮动元素或其他边界。
  2. 边距折叠阻止

    • 在同一个BFC中的相邻块级元素的垂直外边距会发生折叠(即取两者中较大的一个作为最终外边距)。
    • 不同BFC之间的元素则不会发生垂直外边距折叠。
  3. 浮动元素包容

    • BFC能够包容其内部所有的浮动元素,即使这些浮动元素导致了高度塌陷,BFC的边框也能扩展以包含它们,从而解决了浮动元素对后续元素布局的影响问题。
  4. 布局限制

    • BFC内部的元素不会与外部浮动元素重叠。

创建BFC的常见方式包括但不限于:

  • 设置 float 属性值不为 none 的元素。
  • 设置 position 属性值为 absolute 或 fixed 的元素。
  • 设置 display 属性值为 inline-blocktable-celltable-caption 或 flexgrid 等。
  • 设置 overflow 属性值不为 visible 的块级元素。

通过创建BFC,开发人员可以更好地控制布局,解决由于浮动引起的许多布局问题,并实现更为精确的页面布局设计。

伪类

CSS伪类(Pseudo-classes)是CSS选择器中的一种特殊类别,它们用于选择元素基于特定状态而非其内容或属性值。伪类可以帮助开发者根据用户交互、DOM树关系、导航历史等动态条件为元素添加样式。

以下是几个常见的CSS伪类:

  1. 用户交互伪类

    • :hover:当鼠标悬浮在元素上时匹配。
    • :active:当元素被激活(例如,被点击时)匹配。
    • :focus:当元素获得焦点时匹配(例如,通过键盘Tab键访问或点击元素)。
  2. 结构性伪类

    • :first-child:选择元素在其父元素的第一个子元素时匹配。
    • :last-child:选择元素在其父元素的最后一个子元素时匹配。
    • :nth-child(n):选择其父元素的第n个子元素时匹配,可以是数字、关键词(even、odd)或者公式。
    • :not(selector):选择不匹配指定选择器的元素。
    • :only-child:如果元素是其父元素中唯一的子元素,则匹配。
    • :empty:如果元素没有子元素(包括文本节点)时匹配。
  3. 链接伪类

    • :link:匹配尚未访问过的链接(a元素)。
    • :visited:匹配用户已访问过的链接。
    • :target:当锚点(id)与当前URL片段标识符匹配时匹配。
  4. 表单控件状态伪类

    • :enabled:匹配可用的表单控件(如input、select等)。
    • :disabled:匹配禁用的表单控件。
    • :checked:匹配被选中的表单控件,如复选框(checkbox)或单选按钮(radio button)。
  5. CSS Grid 和 Flexbox 伪类

    • :nth-of-type-an 和 :nth-last-of-type(n):在CSS Grid或Flexbox布局中,根据元素在某一类型中的位置选择元素。
    • :nth-last-child(n) 和 :nth-child(-n+3):在布局中选择特定位置的元素。

使用伪类的例子:

Css
/* 鼠标悬停时改变链接颜色 */
a:hover {
  color: red;
}

/* 第一个段落背景色为浅灰色 */
p:first-child {
  background-color: lightgray;
}
0
/* 已访问过的链接变为紫色 */
a:visited {
  color: purple;
}

/* 表单中被选中的复选框文字颜色为绿色 */
input[type=checkbox]:checked + label {
  color: green;
}

这些伪类有助于构建更加动态和交互性强的Web界面,使得CSS能够根据元素的状态而非静态属性来定义样式。

媒体查询

CSS媒体查询(Media Queries)是CSS3的一个强大特性,它允许开发者根据设备的不同特性(如视口尺寸、屏幕分辨率、设备方向、色彩能力等)来应用不同的CSS样式规则。媒体查询的主要用途在于创建响应式网站设计,使得网页能根据访问它的设备环境动态地调整布局、字体大小和其他视觉表现。

在实际编写CSS时,媒体查询通常采用@media规则的形式:

Css
@media media-type and (media-feature) {
  /* 当媒体类型和媒体特性满足条件时,这里的CSS样式将会生效 */
  selector {
    property: value;
  }
}
  • media-type 指定媒体类型,最常见的是 screen(用于电脑屏幕、手机和平板)、print(用于打印预览)等,现在几乎总是默认使用 screen

  • media-feature 是一组媒体特性及其值的表达式,比如:

    • width:设备视口宽度。
    • height:设备视口高度。
    • orientation:设备的方向,可以是 portrait 或 landscape
    • resolution:设备的分辨率。

    例如:

Css
/* 当视口宽度小于或等于600px时 */
@media screen and (max-width: 600px) {
  body {
    background-color: lightblue;
  }
}

/* 当视口宽度大于600px但小于900px时 */
@media screen and (min-width: 600px) and (max-width: 900px) {
  .my-class {
    font-size: 18px;
  }
}

通过这样的方式,设计师和开发者可以确保网页在不同尺寸和类型的设备上都能提供良好的用户体验,实现了内容的适应性和可访问性。随着移动设备和高清显示屏的普及,媒体查询已经成为现代前端开发不可或缺的一部分。

grid布局

juejin.cn/post/685457…

CSS Grid布局(又称网格布局)是CSS中的一种先进的二维布局系统,它允许开发者创建复杂的、响应式的网页布局,能够精确地控制元素在水平和垂直方向上的排列和对齐。Grid布局体系相较于传统的布局模式(如Flexbox、表格布局、定位布局等)提供了更多的灵活性和精细控制。

Grid布局的核心概念主要包括:

  1. 网格容器(Grid Container) :通过设置display: grid属性,可以使一个元素成为一个网格容器,对其后代元素应用网格布局。
  2. 网格项(Grid Items) :网格容器的直接子元素自动成为网格项,它们将在网格容器内按照定义的布局规则排列。
  3. 网格线(Grid Lines) :网格线是划分网格的分界线,包括行线(row lines)和列线(column lines)。可以通过grid-template-columns和grid-template-rows定义网格的列和行数以及每一行和每一列的大小。
  4. 网格轨道(Grid Tracks) :两根相邻网格线之间的区域就是网格轨道,可以用来放置网格项。
  5. 网格单元格(Grid Cells) :一个行网格线和一个列网格线交叉形成的单元格。
  6. 网格区域(Grid Areas) :可以将多个单元格合并成一个更大的区域,为网格项分配位置。
  7. 定位网格项:通过grid-column-start/grid-column-end和grid-row-start/grid-row-end属性,可以精确指定网格项占据的网格单元格或区域。
  8. 自动填充和自动间隔(Auto-fill & Auto-fit) :可以使用这两个关键词根据容器大小自动创建和调整网格轨道的数量。
  9. 对齐与分布:Grid布局提供了丰富的对齐选项,允许开发者精确控制网格项在网格内的对齐方式,包括行和列的起始、结束、居中、拉伸等对齐,以及网格项在空闲空间内的分布方式。
  10. 响应式布局:通过媒体查询,可以根据视口大小或设备特性灵活调整网格布局。

通过Grid布局,开发者可以轻易地创建复杂的网格布局,无论是固定的、响应式的还是自适应的,都能够很好地适应各种设备和屏幕尺寸,极大地增强了网页布局设计的能力和灵活性。

flex布局

www.ruanyifeng.com/blog/2015/0…

www.ruanyifeng.com/blog/2015/0…

FLEX布局,全称为Flexible Box布局模型,是一种CSS布局模式,专为改进网页布局的一致性和灵活性而设计。在Flex布局中,容器(父元素)能够改变其子元素的宽、高以及顺序,以最优方式填充可用空间,或者根据需要调整大小以适应容器空间的变化。

以下是Flex布局的核心概念和特点:

  1. Flex容器(Flex Container) :任何元素只要设置了 display: flex; 或 display: inline-flex; 就会变成一个Flex容器。容器内的子元素将会作为Flex项目(Flex Items)参与布局。
  2. 主轴(Main Axis)与交叉轴(Cross Axis) :Flex布局中有两个关键轴向。主轴是Flex项目沿着容器的主要方向排列的轴线,而交叉轴则是与主轴垂直的轴线。
  3. Flex方向(flex-direction) :通过 flex-direction 属性可以设定主轴的方向,如 row(默认,水平从左到右)、row-reversecolumn(垂直从上到下)、column-reverse
  4. Flex流(Flex Wrap) :通过 flex-wrap 属性控制Flex项目是否能在一条轴线上换行,如 nowrap(默认,不换行)、wrap(允许换行)和 wrap-reverse(反向换行)。
  5. 对齐方式(Justify Content / Align Items / Align Self) :这些属性分别用于控制Flex项目在主轴上的对齐方式、在交叉轴上的对齐方式以及单个Flex项目本身的对齐方式。
  6. Flex生长因子(Flex Grow)与收缩因子(Flex Shrink) :Flex项目可以根据 flex-grow 和 flex-shrink 属性值按比例放大或缩小自身尺寸,以填充容器剩余空间或适应容器空间减小时的情况。
  7. Flex基值(Flex Basis) :通过 flex-basis 属性可以指定Flex项目在分配空间之前的基础尺寸。

总之,Flex布局以其强大的灵活性和响应性著称,能够轻易实现对齐、方向调整、空间分配等各种复杂的布局需求,特别适合移动端和响应式网页设计。随着现代浏览器对Flexbox规范的广泛支持,它已经成为Web开发中布局设计的重要工具之一。

CSS动画

CSS动画是CSS3引入的一种强大特性,允许开发者通过纯CSS代码创建丰富的动态效果。CSS动画能够使HTML元素从一种样式逐渐、平滑地过渡到另一种样式,从而实现动画效果,无需依赖JavaScript或其他插件。

CSS动画主要包括两个关键部分:

  1. @keyframes 规则

    • @keyframes关键字用于定义动画的序列,其中包含了动画过程中不同阶段的样式。

    • @keyframes内部,通过百分比(如0%, 25%, 50%, 75%, 100%)来指定动画的进度点,并在每个进度点处设置元素的不同样式。

    • 可以使用关键词from代表0%,to代表100%,例如:

      Css
       @keyframes move {
         from { width: 100px; }
         to { width: 200px; }
       }
      
  2. 动画应用

    • 使用animation属性将动画应用到具体的HTML元素上。

    • animation属性是一个复合属性,它可以接受多个子属性来定义动画的各个方面,包括:

      • animation-name:指定要使用的@keyframes动画名称。
      • animation-duration:定义动画完成一个周期所花费的时间。
      • animation-timing-function:定义动画的速度曲线(如ease、linear、ease-in-out等)。
      • animation-delay:动画开始前的延迟时间。
      • animation-iteration-count:动画重复的次数(如无限循环可以用infinite)。
      • animation-direction:决定动画是否反向播放(如正向、反向、交替)。
      • 其他还有animation-fill-mode(动画结束后如何填充样式)等属性。

例如,将上面定义的move动画应用到一个元素上:

Css
 div {
   animation: move 1s ease-in-out infinite;
 }

这样,指定的div元素就会按照move动画定义的内容,以1秒钟的持续时间、ease-in-out的缓动效果无限次地执行宽度从100px到200px的变化动画。

transitions

CSS Transitions API 是CSS3中的一项重要特性,它允许开发者定义当一个CSS属性从一个值改变到另一个值时的过渡效果,从而实现了平滑、连续的动画效果。这种过渡不需要借助JavaScript,仅通过CSS就能完成,既节省资源又提高了效率。

以下是一些关键概念和用法:

关键属性

  1. transition-property

    • 定义哪些CSS属性会发生过渡效果。可以指定单个属性,多个属性,或者使用all关键字表示所有可以过渡的属性。
    Css
     .example {
       transition-property: background-color, transform;
     }
    
  2. transition-duration

    • 设置过渡效果持续的时间,单位通常是秒(s)或毫秒(ms)。
    Css
      .example {
       transition-duration: 0.5s;
     }
    
  3. transition-timing-function

    • 定义过渡过程的速度曲线,例如线性、加速然后减速、先慢后快等。常用的有ease、linear、ease-in、ease-out、ease-in-out、cubic-bezier()函数等。
    Css
     .example {
       transition-timing-function: ease-in-out;
     }
    
  4. transition-delay

    • 设置过渡开始前的延迟时间。
    Css
     .example {
       transition-delay: 0.2s;
     }
    

简写形式

上述四个属性可以合并为一个简写属性transition

Css
 .example {
   transition: property duration timing-function delay;
 }
 
 /* 示例 */
 .example {
   transition: background-color 0.5s ease-in-out 0.2s, transform 0.8s linear;
 }

使用场景

  • 当鼠标悬停(:hover)、获取焦点(:focus)或其他触发状态改变时,元素的某个或多个样式会平滑过渡到新的状态。
Css
 .button {
   background-color: lightblue;
   transition: background-color 0.3s;
 }
 
 .button:hover {
   background-color: darkblue;
 }

在这个例子中,当.button元素被鼠标悬停时,其背景色将在0.3秒内平滑过渡到深蓝色。

总之,CSS Transitions API简化了网页动画的制作流程,并提供了流畅、自然的视觉效果,大大提高了用户体验。

transform

CSS Transform 属性是用来在二维或三维空间中操纵元素的外观,包括旋转、缩放、移动(平移)、倾斜等操作。这个属性允许开发者对元素的位置和形状进行动态变化,且这些变化不会影响文档流中的其他元素布局。Transform 的强大之处在于它能够实现复杂的动画效果和交互式设计,尤其是在现代Web开发中配合CSS Transition 和 Animation 来创建平滑的变换动画。

以下是一些关键的Transform方法:

  1. rotate()

    • 用于旋转元素。接受度数作为参数,正数代表逆时针旋转,负数代表顺时针旋转。
    Css
     .rotate-element {
       transform: rotate(45deg);
     }
    
  2. translate()

    • 用于平移元素。接受水平(x轴)和垂直(y轴)方向的距离作为参数,单位可以是像素(px)、百分比(%)等。
    Css
     .translate-element {
       transform: translate(50px, 100px);
     }
    
  3. scale()

    • 用于缩放元素。接受两个参数分别对应X轴和Y轴的缩放比例,如果只提供一个参数,则X轴和Y轴按相同比例缩放。
    Css
     .scale-element {
       transform: scale(1.5); /* 同比例放大1.5倍 */
     }
    
  4. skew()

    • 用于使元素倾斜。接受两个参数分别表示X轴和Y轴的倾斜角度。
    Css
     .skew-element {
       transform: skew(20deg, 10deg);
     }
    
  5. matrix()

    • 用于更复杂的二维或三维变换,它接收六个参数,可以同时完成旋转、缩放和平移操作。
    Css
    .matrix-element {
       transform: matrix(1, 2, 3, 4, 5, 6);
     }
    

此外,还有三维变换如:

  • rotateX()rotateY()rotateZ() 或 rotate3d() 对元素进行三维旋转
  • translate3d()translateZ() 进行三维平移
  • scale3d()scaleZ() 进行三维缩放

综合示例:

Css
 element {
   transform: translateX(50px) translateY(100px) rotate(45deg) scale(1.5);
 }

以上代码会使.element首先向右平移50px,向下平移100px,接着旋转45度,最后整体缩放至1.5倍大小。同时,结合CSS Transition或Animation属性,可以轻松实现这些变换的动画效果。

CSS硬件加速

在CSS中,为了提升动画性能和利用设备的GPU来提高渲染速度,可以通过开启硬件加速来优化页面上的动画效果。这通常涉及到使用一些特定的CSS属性,特别是当涉及到transform和opacity属性的动画时,浏览器会自动触发硬件加速。

以下是如何开启硬件加速的几种方式:

  1. 使用 transform: translateZ(0) 或 translate3d(0, 0, 0)

    • 将一个3D变换应用到元素上有时可以强制浏览器使用GPU来渲染该元素及其动画。
    Css
    .accelerated-element {
      transform: translate3d(0, 0, 0);
    }
    

    即使没有实质性的3D变换,仅添加这一属性也可以触发硬件加速。

  2. 使用 will-change 属性:

    • 提前告知浏览器某个属性即将发生变化,并可能需要硬件加速。
    Css
    .animating-element {
      will-change: transform; /* 或 opacity 等需要加速的属性 */
    }
    

    注意:过度使用 will-change 可能会导致内存占用增加,因此应在真正需要时才声明,并在动画结束时撤销声明。

  3. 在现代浏览器中,对 transform 和 opacity 属性的应用通常会自动触发硬件加速,所以只要直接使用这些属性做动画,就很可能已经启用了硬件加速。

例如,当你为元素定义了一个包含动画的keyframes规则:

Css
 @keyframes slideIn {
   from {
    transform: translateX(-100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
0}

.accelerated-animation {
  animation: slideIn 1s ease-in-out forwards;
}

在这个例子中,由于使用了 transform 和 opacity 动画,浏览器很可能会自动启用硬件加速来提升动画性能。但是,对于更复杂的情况或者老旧的浏览器,可能需要手动通过上述技术开启硬件加速。

CSS硬件加速原理

硬件加速,尤其是在Web开发中的CSS领域,是指浏览器利用图形处理单元(GPU)来帮助渲染复杂的图形和动画,而不是单纯依赖CPU的软件渲染。这是因为GPU设计用于并行处理大量与图形相关的计算任务,特别适合用来渲染3D变换、复合层以及动画效果,其效率远高于CPU。

当CSS中开启了硬件加速,浏览器会将部分渲染工作转移到GPU上,创建一个新的“合成层”(composited layer),并将该层存储在GPU内存中独立渲染。这意味着每次更新时,GPU可以直接操作这个层的内容而不需要重新构建整个页面的像素数据,大大提高了渲染效率。

以下是几个开启硬件加速的CSS属性及背后原理:

  1. Transforms:3D变换如translate3drotate3dscale3d等,即使只是简单的translateZ(0)也能触发创建一个新的合成层,因为GPU专长于处理三维空间内的变换。
  2. Opacity:更改元素的不透明度(opacity)也会促使浏览器创建合成层,因为GPU可以高效地混合不同透明度的图层。
  3. will-change:此属性可以提示浏览器即将发生的改变可能需要硬件加速,浏览器可以根据这个提示提前分配资源和创建合适的合成层。
  4. 动画和过渡:CSS动画和过渡如果涉及到了上述属性,也有可能自动触发硬件加速。

总的来说,通过上述CSS属性的运用,浏览器能够识别出哪些元素的渲染过程可以受益于GPU,并相应地调整其渲染策略,从而实现硬件加速。这样做的目的是减少主线程的工作负担,加快渲染速度,提升用户体验,尤其是对于那些包含复杂动画或交互的网页而言。然而,值得注意的是,虽然硬件加速有助于提升性能,但它也有潜在的成本,比如消耗更多内存,且不适合所有场景,因此应当谨慎使用并针对具体情况进行性能测试与优化。


JavaScript

Node.js

TypeScript

设计模式

单一职责原则

最少知识原则

开放封闭原则

发布订阅模式

单例模式

命令模式

代理模式

策略模式

装饰者模式

适配器模式

工程化工具

构建工具

版本控制

git

前端框架

React

Next.js

Next.js 是一个基于 React 的开源 JavaScript 框架,专为构建高效的服务器端渲染(Server-Side Rendering, SSR)和静态站点生成(Static Site Generation, SSG)的 web 应用而设计。它在 React 的基础上提供了开箱即用的路由、页面优化、静态资源管理、代码分割等功能,并且易于配置和扩展。

Next.js 的主要特点和功能包括:

  1. 服务器端渲染 (SSR) :Next.js 默认支持服务器端渲染,这意味着初始页面可以在服务器上生成并直接发送给浏览器,从而提升 SEO 性能和页面加载速度,同时保持了 SPA(单页应用)的交互体验。
  2. 静态站点生成 (SSG) :Next.js 支持静态生成,允许你预先渲染所有页面为纯静态 HTML 文件,这对于无需服务器实时动态响应的静态博客、文档站点等十分有用,有助于大幅度提高加载速度和降低成本。
  3. 零配置:Next.js 提倡简洁的开发体验,很多基础配置如热重载、CSS 解析等都已经内置,开发者可以快速启动项目并专注于业务逻辑开发。
  4. 路由系统:Next.js 自动处理页面级别的路由,根据文件夹结构映射到 URL,同时也支持动态路由和自定义路由。
  5. 代码分割和懒加载:Next.js 内置了代码分割功能,自动将代码切割成多个较小的 chunk,实现按需加载,有效减小首次加载的体积,提高页面加载速度。
  6. 静态资源处理:通过内置的 webpack 配置,Next.js 可以轻松处理静态资源(如图片、CSS、JavaScript 文件)的导入和优化。
  7. API Routes:Next.js 提供了一种简便的方式来创建后端API,这些API可以直接在 Next.js 项目中编写,并与前端页面紧密结合。
  8. 国际化 (i18n) 支持:Next.js 内置了国际化支持,使得开发多语言网站变得容易。
  9. 自定义服务器:尽管 Next.js 默认提供了内置服务器,但也可以根据需要定制自定义的 Node.js 服务器。
  10. 内置性能优化:Next.js 为开发者提供了很多性能优化的工具和建议,如自动静态优化、预渲染、延迟加载等。

总之,Next.js 结合了 React 的优秀开发体验和现代 web 应用所需的各种最佳实践,旨在简化开发流程,提高开发效率,并帮助开发者构建高性能、易维护的 web 应用程序。

Vue

笔试部分

数据结构与算法

面试经典 150 题

LeetCode 热题 100

剑指Offer

juejin.cn/post/696871…

juejin.cn/post/684490…

juejin.cn/post/698390…

扩展知识点

面试

PWA

juejin.cn/post/684490…

PWA,全称Progressive Web App(渐进式网络应用),是一种先进的Web应用程序设计模式和技术集合,它结合了Web应用和原生应用的优点,旨在通过现代Web技术提供更加接近原生应用的用户体验。PWA的关键特征包括但不限于:

  1. 渐进增强:适用于任何浏览器,但特别针对支持PWA特性的现代浏览器进行了优化,确保即使在不支持的环境下也能提供基本功能。
  2. 响应式设计:无论用户是在手机、平板还是桌面电脑上访问,都能自动适应屏幕尺寸和方向,提供一致且良好的交互体验。
  3. 离线能力:利用Service Worker和Cache API等技术,使得PWA能够在没有网络连接的情况下依然可以正常工作或者展示部分内容。
  4. 安装性:允许用户将PWA添加到他们的主屏幕上,看起来和行为类似原生应用,无需通过应用商店下载安装。
  5. 推送通知:如同原生应用一样,PWA可以接收后台推送的消息通知。
  6. 安全:所有的PWA都需要通过HTTPS提供,保证通信安全。
  7. 快速加载:通过预加载和资源缓存策略,PWA能够快速启动和响应用户的操作。

PWA的优势在于它们易于发现(通过搜索引擎等)、易于安装和更新,而且因为基于Web标准,开发者只需要维护一套代码即可适配多种平台。随着浏览器技术的发展,PWA的支持度不断提高,越来越多的企业和开发者开始采用这一技术来改进Web应用的用户体验和留存率。

WebAssembly

juejin.cn/post/701328…

WebAssembly(通常缩写为Wasm)是一种低级的类汇编语言的二进制格式,它是为现代网络浏览器设计的一个开放标准,旨在作为一种可移植的目标代码格式,允许开发者将高级语言(如C、C++、Rust等)编译成能在所有现代浏览器上高效运行的代码。WebAssembly具有以下几个关键特性:

  1. 可移植性:WebAssembly的设计使其能在不同操作系统和硬件架构之间无缝运行,尤其在网络浏览器环境中表现卓越,但也支持非浏览器环境如Node.js以及其他非Web环境。
  2. 安全性:WebAssembly在设计时充分考虑了沙箱机制,确保代码在浏览器中安全执行,无法直接访问主机环境而不经过适当的API调用。
  3. 性能:由于其紧凑的二进制格式和接近机器语言的特性,WebAssembly的解析和执行速度非常快,可提供接近原生代码的性能。
  4. 可集成性:WebAssembly模块可以直接与JavaScript交互,允许现有JavaScript生态系统中的库和框架轻松地与高性能的WebAssembly模块协同工作。
  5. 开源标准:WebAssembly由W3C社区小组共同制定,并得到了所有主流浏览器厂商的支持,已经成为Web标准的一部分。

WebAssembly旨在解决JavaScript在处理某些计算密集型任务时可能遇到的性能瓶颈问题,同时保持Web平台的安全性和向后兼容性。通过WebAssembly,开发者可以编写更复杂的应用程序,如游戏引擎、图像处理、音频处理、加密算法等,并在Web浏览器上获得更高的执行效率。

JWT

juejin.cn/post/723255…

JWT(JSON Web Tokens)是一种开放标准(RFC 7519),用于在网络应用环境间安全地传输声明(claims)。JWT本质上是一个经过数字签名或加密的JSON对象,能够承载用户的身份验证和授权信息,常用于实现无状态的、基于token的身份验证机制。

JWT的结构由三部分组成,用. 分隔:

  1. Header(头部) :包含了用于生成签名的算法(通常为HS256、RS256等)和令牌类型(typ),通常为{"alg": "HS256", "typ": "JWT"},这个部分会被Base64Url编码。
  2. Payload(载荷) :这部分包含实际传输的数据,可以包含用户身份信息(如用户ID)、权限信息、过期时间(exp)、签发时间(iat)以及其他自定义的声明。载荷必须是经过Base64Url编码的JSON对象。
  3. Signature(签名) :通过对前面的Header和Payload进行编码后,使用Header中指定的算法和服务器的密钥进行签名,确保了JWT在传输过程中不被篡改。

JWT的工作流程大致如下:

  • 客户端(如浏览器)通过用户名和密码登录。
  • 服务器验证用户身份后,生成一个JWT,其中包含用户ID和其他相关信息,并设置了过期时间。
  • 服务器将JWT返回给客户端,客户端通常将其存储在LocalStorage或Cookie中。
  • 客户端在后续请求中将JWT放入HTTP请求头(通常是Authorization header)中,格式通常是Bearer + 空格 + JWT。
  • 服务器收到请求后,验证JWT签名的有效性,以及JWT是否过期等信息,通过验证后即可确定用户身份并提供相应的服务。

JWT的优势在于:

  • 无状态:服务器端无需存储session信息,减轻了服务器的压力。
  • 安全性:通过签名或加密保证数据的完整性和防篡改。
  • 跨域:适合于分布式系统,因为JWT可以在多个服务之间传递用户身份。

需要注意的是,JWT的安全性取决于密钥的保管,如果密钥泄露,可能会导致签名验证失效,进而影响系统的安全性。同时,JWT过期策略也很重要,以防止过期的JWT继续被使用。

WebRTC

WebRTC(Web Real-Time Communication)是一项允许网页浏览器进行实时通信(RTC)的技术标准,它允许网络应用提供音视频通信功能,无需任何插件或软件下载。WebRTC由一组API和协议组成,能够让网页应用直接在浏览器之间进行点对点(Peer-to-Peer, P2P)的实时音视频通信,以及数据共享。

这项技术的核心组件包括:

  1. getUserMedia API:允许浏览器访问用户的摄像头和麦克风,捕捉音视频流。
  2. RTCPeerConnection API:负责建立和维护两个浏览器之间的点对点连接,通过ICE(Interactive Connectivity Establishment)协议进行网络穿透(NAT Traversal),确保两个浏览器可以直接通信。
  3. RTCDataChannel API:提供浏览器之间高效、低延迟的双向数据通道,可用于发送任意类型的数据。
  4. SDP (Session Description Protocol)  和 ICE (Interactive Connectivity Establishment)  协议:SDP用于描述通信会话的元数据,如音视频编码格式、带宽需求等;ICE则用于找出穿越NAT和防火墙的最佳路径。

通过WebRTC,开发者可以构建如视频会议、语音通话、实时协作应用等Web应用,使得用户能够在浏览器上享受高质量的实时通信体验。WebRTC标准由W3C和IETF共同制定,并得到各大主流浏览器的支持。

Electron

Electron 是一个开源的跨平台桌面应用开发框架,由GitHub公司开发并维护。它允许开发者使用JavaScript、HTML和CSS(以及Node.js)构建原生桌面应用程序,这些应用程序可以运行在Windows、macOS和Linux等操作系统上。

Electron的核心思想是将Chromium(Google Chrome的开源项目)浏览器引擎与Node.js环境相结合,形成一个完整的桌面应用运行环境。开发者可以利用Web技术构建应用的用户界面,同时利用Node.js的强大功能进行文件系统操作、网络通信、系统API调用等本地操作。

通过Electron,开发者可以复用现有的Web开发技能来构建桌面应用,降低了开发门槛,而且由于使用的是Web技术栈,代码可以轻松地跨平台运行。知名的桌面应用如Visual Studio Code、Atom编辑器、Slack等都是基于Electron构建的。

在Electron中,主进程(Main Process)负责管理应用程序的生命周期、窗口、菜单、托盘图标等系统相关的功能,而渲染进程(Renderer Process)则是每个应用程序窗口内部的Web页面,负责展示用户界面和处理大部分业务逻辑。主进程和渲染进程之间可以通过IPC(Inter-Process Communication)通信机制进行数据交换和同步。

Electron的应用场景广泛,特别适用于需要构建跨平台桌面应用,并希望利用Web开发技术栈降低开发成本和时间投入的情况。

移动优先策略

移动优先策略(Mobile-First Strategy)是一种现代Web设计和开发方法论,强调从最小的屏幕(如智能手机)开始设计和构建网站或应用,然后再逐渐扩展到更大屏幕(如平板和桌面)。这一策略源于越来越多的用户通过移动设备访问互联网的趋势,以及响应式Web设计(Responsive Web Design, RWD)的需求。

移动优先策略的核心要点包括:

  1. 内容优先设计:设计师和开发者首先关注内容和功能的核心价值,去除冗余内容,优先保证在小屏幕设备上用户体验良好。简洁的布局、高效的导航和快速加载的内容是移动优先设计的重点。
  2. 响应式设计:采用响应式设计技术,确保网站布局、图片和功能可以根据设备屏幕大小和方向自适应调整。这意味着同一套代码可以适应不同尺寸的屏幕,而不仅仅是为移动设备单独设计一套方案。
  3. 触摸友好交互:考虑到移动设备普遍使用触摸屏,移动优先策略会优化界面元素的大小和间距,确保用户可以通过手指轻松操作,例如增大点击区域、减少需要精确点击的元素等。
  4. 性能优化:鉴于移动设备可能存在的网络限制,移动优先策略还会注重性能优化,如减少HTTP请求、压缩文件、延迟加载非关键资源等,以加快页面加载速度和降低数据消耗。
  5. 渐进增强:随着屏幕尺寸和功能能力的增加,可以逐步增加更多的交互元素、更复杂的功能和更丰富的视觉表现。这意味着基础功能和内容在所有设备上都能访问,而高级功能和优化的用户体验则在支持的设备上得到增强。

总之,移动优先策略的核心理念是确保所有用户,无论使用何种设备,都能获得良好的基础体验,同时在条件允许的情况下提供更高级别的交互和视觉效果。这种策略有助于构建更加包容和普适的Web产品,符合现代多设备互联的网络环境需求。

WebAssembly

WebAssembly(简称Wasm)是一种低级别的可移植字节码格式,专为现代网络浏览器设计,允许开发者将高级语言(如C、C++、Rust等)编译成能在所有现代浏览器上高效运行的代码。WebAssembly旨在补充JavaScript,尤其是对于需要高性能计算、图形处理、游戏引擎、加密算法等场合,提供接近原生应用的性能。

WebAssembly的特点和优势包括:

  1. 可移植性:Wasm代码是平台无关的,可以在不同的操作系统和浏览器环境中无缝运行,因为它会被编译为目标环境所理解的指令集。
  2. 性能:Wasm模块以紧凑的二进制格式传输和执行,解析和执行速度快,近似于本地机器码的性能。同时,Wasm的设计使得它能够有效利用现代CPU的优化特性。
  3. 安全性:WebAssembly运行在浏览器的安全沙箱环境中,无法直接访问主机资源,必须通过JavaScript提供的API进行安全访问,保障了用户的安全。
  4. 可集成性:Wasm模块可以直接与JavaScript交互,JavaScript可以加载和调用Wasm模块中的函数,反之亦然,从而实现混合编程。
  5. 开源标准:WebAssembly由W3C社区小组共同制定,获得了所有主流浏览器厂商的支持,已成为Web标准的一部分。

WebAssembly的使用流程通常包括:

  • 编译:将高级语言编译为Wasm二进制格式。
  • 加载:通过JavaScript API加载Wasm模块到浏览器。
  • 实例化:创建Wasm实例,绑定到JavaScript的函数和内存。
  • 调用:在JavaScript中调用Wasm模块中的函数。

WebAssembly的意义在于,它为Web平台带来了原生级别的性能,同时保持了Web的安全性和可移植性,使得开发者能够利用熟悉的语言开发高性能Web应用,克服JavaScript在某些计算密集型任务上的性能瓶颈。

CSS in JS

CSS in JS 是一种将 CSS 样式直接编写在 JavaScript 中的现代化样式编写方式,它改变了传统的分离样式(CSS)和结构(HTML)的做法,将样式和组件的逻辑紧密结合在一起,通常在现代前端框架(如React、Vue)中被广泛应用。

CSS in JS 的优点包括:

  1. 样式与组件逻辑紧密耦合:CSS in JS 让样式成为组件的一部分,确保样式和组件的生命周期紧密关联,防止样式覆盖和命名冲突问题。
  2. 模块化和可复用:CSS in JS 方案大多支持模块化和组件化,可以很容易地将样式封装在组件内,实现样式与组件的同步复用和导入导出。
  3. 动态样式:在 JavaScript 中编写样式可以方便地利用变量、条件判断和函数来动态生成样式,这对基于状态变化的动态样式尤为适用。
  4. 更好的代码组织:CSS in JS 可以很好地与模块化工具(如Webpack)整合,使得样式代码可以按照组件目录结构组织,利于维护和查找。
  5. 更好的开发体验:许多 CSS in JS 库支持自动编译和热更新,提高开发效率。

几种常见的 CSS in JS 库和方式包括:

  • Styled Components:一个在React生态中流行的库,它允许开发者通过编写JavaScript模板字符串创建样式化的React组件,样式直接作用于组件。
  • Emotion:与Styled Components相似,也是一个用于React、Vue、Angular等框架的CSS in JS解决方案,提供了更快的渲染速度和更多的灵活性。
  • JSS:一个通用的JavaScript库,可以将CSS编写为JavaScript对象,同时支持React和其他框架。
  • CSS Modules:虽然不是严格意义上的CSS in JS,但CSS Modules通过构建工具为CSS类名添加哈希值,实现样式作用域的局部化,可以看作是CSS in JS的一种变体。
  • StitchesLinariaGlamor等也是其他受欢迎的CSS in JS库。

当然,CSS in JS 也有一些争议点,比如可能导致CSS难以全局管理和复用、增大包体积、对SEO和性能有一定影响等。因此,在实际项目中是否使用CSS in JS还需权衡利弊,结合项目需求和技术选型决定。

Accessibility无障碍访问

无障碍访问(Accessibility,简称A11y)是指确保任何人,无论其身体能力如何,都能有效地访问和使用Web内容和Web应用的技术措施。这意味着残疾人(如视力障碍、听力障碍、运动障碍、认知障碍等)也能通过辅助技术(如屏幕阅读器、放大镜、键盘替代输入法、语音识别等)与网站或应用进行交互,获取信息和服务。

实现无障碍访问的关键原则和实践包括:

  1. 结构清晰的HTML:使用正确的HTML元素来标记内容,如使用<header><main><nav><section><article><aside><footer>等语义化标签,确保内容有明确的层次结构,以便辅助技术可以正确解读和传达给用户。
  2. 可访问的互动元素:所有可交互控件都需要有可聚焦状态,并且可通过键盘操作。例如,按钮要有明确的标签,表单控件要有适当的标签和提示,以及使用tabindex属性合理设置焦点顺序。
  3. 色彩对比度和非视觉线索:确保文本和背景有足够的色彩对比度,以便视力障碍者能够看清内容。同时,不能仅依赖颜色来传达信息,应提供额外的视觉以外的线索,如图标旁的文字描述、悬停提示等。
  4. 图像和多媒体的替代文字:所有<img>标签都应该有alt属性来提供替代文字描述,而对于多媒体内容如视频和音频,应提供字幕、隐藏式字幕或转录文本。
  5. ARIA属性:使用WAI-ARIA(Web Accessibility Initiative - Accessible Rich Internet Applications)属性来增强Web应用的可访问性,为非标准元素添加角色、状态和属性,帮助辅助技术理解组件的用途和交互方式。
  6. 可导航的Headings和Landmarks:正确使用标题(Heading)层级,确保内容逻辑清晰,并利用ARIA Landmark Roles来标识页面的主要区域,如role="navigation"role="main"等。
  7. 键盘操作友好的设计:确保所有功能都能通过键盘操作,不依赖鼠标,这不仅有助于无障碍访问,还能提高常规用户在无鼠标情境下的体验。

通过遵循WCAG(Web Content Accessibility Guidelines)标准,网站和Web应用可以达到不同程度的无障碍等级(A、AA、AAA),以满足不同国家和地区法律规定的无障碍要求,同时提升整体用户体验。

Three.js

Three.js 是一个基于WebGL的JavaScript库,用于在浏览器中创建和展示三维图形。它封装了WebGL的复杂性,为开发者提供了一系列高级API,使得开发2D/3D图形和动画变得更加直观和便捷。Three.js可以创建包括3D模型、动画、粒子系统、光线投射、阴影、物理模拟等多种视觉效果,并且与HTML5 canvas和SVG无缝集成,能够在网页中构建交互式的3D应用程序和游戏。

通过Three.js,开发者可以使用JavaScript和WebGL绘制和操纵三维对象,创建场景、摄像机、光源、材质、几何体以及各种特效。Three.js支持多种3D文件格式导入,并且因其跨平台和良好的浏览器兼容性,使得Web3D内容开发变得大众化和流行。

例如,开发者可以使用Three.js构建3D产品展示、数据可视化、虚拟现实(VR)场景、增强现实(AR)应用、游戏场景等丰富的三维交互体验。Three.js大大降低了Web3D开发的入门门槛,让更多Web开发者能够涉足3D内容创作领域。

MSE

Media Source Extensions (MSE) API 是一项Web浏览器的扩展功能,它允许网页应用以低级别控制媒体流在HTML5 <video> 和 <audio> 元素中的播放。MSE允许开发者以分段(chunk)形式向媒体元素提供媒体数据,而不是仅仅通过 src 属性加载完整的媒体文件。这种机制使得网页能够处理自定义的媒体流,比如从服务器动态获取的流媒体数据,或者是经过自定义编码、加密或处理过的媒体内容。

通过MSE API,开发者可以将媒体数据以MIME类型(如video/mp4、video/webm等)的Uint8Array缓冲区形式送入MediaSource对象,然后将MediaSource对象绑定到媒体元素,从而实现自定义的流媒体播放功能。MSE常用于实现点播和直播流媒体服务,特别是在适应不同网络状况下的自适应流(adaptive streaming)技术,如DASH和HLS等。

简而言之,Media Source Extensions API为Web开发人员提供了更低层级的媒体处理能力,促进了更加灵活和高级的视频播放解决方案的实现。

flv.js

flv.js 是一个开源的JavaScript库,由Bilibili开发并维护。这个库使得现代浏览器能够在不借助任何插件的情况下直接播放FLV格式的视频文件。FLV是一种曾经在网页视频领域广泛应用的流媒体格式,但由于原生HTML5 <video> 元素并不支持FLV格式,因此在HTML5时代FLV视频的播放遇到了挑战。

flv.js通过JavaScript实现FLV文件的解析和解码,然后利用浏览器提供的Media Source Extensions (MSE) API将解码后的视频帧注入到HTML5 <video> 元素中进行播放。这样一来,即使浏览器本身不支持FLV格式,也能通过flv.js在网页上流畅播放FLV格式的视频流。flv.js在很大程度上解决了FLV视频在Web平台上兼容性的问题,并在众多视频网站和项目中得到了广泛应用。

HLS

HLS(HTTP Live Streaming)是Apple公司推出的一种基于HTTP协议的流媒体传输协议,主要用于实时和点播音视频内容的分发。HLS协议将视频内容切割成一系列小的、基于HTTP可下载的媒体文件片段(ts或m4s格式),同时还有一个M3U8索引文件来记录这些片段的URL和播放顺序。

通过这种方式,HLS可以实现自适应流媒体,即根据网络条件和客户端设备能力动态切换不同码率的视频流,确保用户在各种网络环境下都能获得流畅的播放体验。HLS广泛应用于iOS、macOS、tvOS等Apple设备,以及许多支持HLS协议的Android设备、智能电视、流媒体盒子及现代浏览器等。

客户端播放HLS内容时,首先下载M3U8索引文件,然后依据索引文件指示逐步下载和播放视频片段。由于HLS基于HTTP协议,所以它能够穿透大多数防火墙和代理服务器,具有良好的网络适应性和广泛的兼容性。

hls.js

hls.js 是一个开源的JavaScript库,用于在现代浏览器中实现HTTP Live Streaming(HLS)协议的视频流播放。HLS是由Apple公司提出的流媒体协议,它将视频内容分割成一系列小的、可通过HTTP协议下载的媒体文件片段(通常是.ts格式),并使用一个M3U8索引文件来指示这些片段的顺序和地址。

hls.js 库通过浏览器的Media Source Extensions (MSE) API,将HLS视频流的各个片段加载到内存中,然后将这些片段串联起来连续播放,从而实现流畅的视频播放体验。该库支持自适应比特率流(ABR),可以根据网络状况自动选择合适的视频质量和比特率,以确保视频播放的稳定性和质量。

hls.js 在各种浏览器中都有很好的兼容性,特别是对于那些原生不完全支持HLS的浏览器,它提供了一个可靠且高性能的解决方案,使得开发者能够方便地在网页中嵌入和播放HLS视频内容。

低代码平台

前端低代码平台是一种软件开发平台,它通过图形用户界面、拖拽组件和配置而非传统的手工编码,大幅减少了前端应用开发所需的代码编写量。这种平台提供可视化的开发环境,允许开发者通过简单的操作构建用户界面和功能模块,而不需要深入掌握复杂的前端开发技术。

低代码前端平台通常具备以下特点:

  1. 可视化开发工具:平台提供了丰富的UI组件库,用户可以通过拖放组件到画布上快速构建页面布局。
  2. 配置驱动:开发者可以使用配置选项代替手写代码来设定组件的属性、样式、交互逻辑等,系统会自动生成相应的前端代码。
  3. 模型驱动:通过数据模型和业务逻辑模型的抽象,使得非专业程序员也能快速搭建出符合业务需求的前端应用。
  4. 扩展性:虽然侧重于低代码开发,但仍保留了扩展接口,允许开发者在必要时介入并编写自定义代码来满足特殊需求。
  5. 跨平台支持:多数低代码前端平台生成的应用能够兼容多种终端设备,如桌面端、移动端(包括iOS和Android)等,实现一次开发,多端适配。
  6. 版本控制和协作:平台支持多人协作开发和版本管理,方便团队成员分工合作并追踪开发进度。

通过前端低代码平台,非技术人员、初级开发者甚至是业务人员都能够参与到应用的开发中来,极大地提升了开发效率,降低了项目周期和成本,尤其适用于快速迭代、敏捷开发的场景。同时,也为专业前端开发者节省了大量重复性工作,让他们能更专注于解决复杂问题和创新性功能的开发。

服务发现

服务发现(Service Discovery)是一种网络架构的概念和技术,它允许网络中的服务实例自动发布自身可用性和位置信息,并允许客户端或服务消费者发现并连接到这些服务。在分布式系统或微服务架构中,服务发现尤为重要,因为在这样的环境中,服务的数量和位置往往是动态变化的,通过服务发现机制可以确保系统的弹性和可扩展性。

服务发现的具体实现方式有很多种,例如:

  1. DNS-Based Service Discovery (DNS-SD):通过扩展DNS系统来发布和查找服务,如苹果公司的Bonjour就是基于此技术。
  2. 使用专门的服务发现软件或平台,如Consul、etcd、Zookeeper、Eureka等,它们提供注册服务实例和查询服务实例的API和工具。
  3. 使用Kubernetes等容器编排系统的内置服务发现功能,服务实例随着Pod的创建和销毁自动注册和注销。
  4. 通过配置中心,服务实例启动时将自己的信息注册到配置中心,消费者通过查询配置中心获取服务实例列表。

服务发现的作用在于简化分布式系统中服务间的相互调用,使得服务之间的连接不再依赖硬编码的地址,而是动态发现并连接到可用的服务实例,增强了系统的稳定性,支持了服务的水平扩展和故障转移。

Bonjour

Bonjour(原名Rendezvous)是Apple Inc.开发的一种网络服务发现和名称解析技术,它基于 Zero Configuration Networking(零配置网络)标准,允许网络中的设备和服务自动发现彼此,而无需用户手动配置网络设置。

Bonjour的核心技术包括以下两点:

  1. Multicast DNS (mDNS) :这是一种允许设备在本地网络中使用标准的DNS(域名系统)协议进行自我宣传的机制,即使没有传统的DNS服务器也可以工作。设备可以为自己的服务注册一个易记的名称,例如MyPrinter.local,并广播到整个局域网中,其他设备可以通过这个名称来找到它。
  2. DNS Service Discovery (DNS-SD) :DNS-SD协议扩展了mDNS的功能,允许设备公布其所提供的服务类型,如打印服务、文件共享服务等,以及如何访问这些服务的相关信息。这样,网络中的其他设备可以自动发现并连接到这些服务。

Bonjour广泛应用于Apple的产品和生态系统中,如Mac OS X、iOS、iPadOS以及AirPrint、AirPlay、HomeKit等服务。此外,其他操作系统和设备也可以通过兼容Bonjour的软件实现与Apple设备和服务的互操作性。在开发层面,有许多编程语言和框架支持Bonjour,允许开发者在自己的应用中集成服务发现功能。

移动端调试策略

移动端调试策略主要包括以下几种方法:

  1. Chrome DevTools(远程调试)

    • USB连接调试:对于Android设备,可以通过USB线将其与计算机相连,然后在Chrome浏览器中启用“开发者工具” -> “更多工具” -> “远程设备”来进行远程调试。对于iOS设备,需要使用Safari浏览器的开发者菜单连接iPhone或iPad。
    • 无线调试:部分Android设备支持无线调试,只需在设备上启用USB调试模式,并设置好无线ADB调试即可。
  2. 移动浏览器开发者工具

    • 大多数现代移动浏览器内置开发者工具,例如在Safari中可以通过Safari > 高级 > 开发 > 打开“开发者菜单”在设备上启用。
    • 对于Chrome浏览器在Android设备上,可以在设置中启用USB调试并连接PC后,在Chrome DevTools中查看和调试移动设备上的网页。
  3. 模拟器和仿真器

    • 使用Chrome DevTools中的设备模式(Device Mode)可以在桌面浏览器中模拟不同移动设备的屏幕尺寸和用户代理字符串。
    • 使用Apple的Simulator或Android Studio的AVD Manager创建虚拟设备进行模拟调试。
  4. 响应式设计检查

    • 使用CSS媒体查询配合开发者工具调整设备视窗尺寸,模拟不同屏幕尺寸下的布局。
  5. 性能分析

    • 利用Lighthouse等工具进行性能审计,确保移动端页面加载速度和性能达标。
    • 使用Timeline或Performance面板分析页面加载、渲染和交互过程中的性能瓶颈。
  6. 真机测试

    • 除了模拟器和仿真器外,务必在真实设备上进行测试,以确保兼容性和性能在多种设备上都正常。
  7. 网络模拟

    • 开发者工具中可以模拟不同的网络条件,如慢速3G、EDGE等,以测试页面在弱网环境下的加载性能。
  8. 使用调试工具

    • 如Weinre、Chrome DevTools Remote Debugging Protocol等远程调试工具,可以进行远程实时调试。
  9. 兼容性测试

    • 使用BrowserStack、CrossBrowserTesting等在线服务,对多种移动设备和浏览器版本进行兼容性测试。

通过以上策略,开发者可以有效地对移动端应用或网页进行调试,优化性能、排查问题并确保在多种设备上的兼容性。

Chrome浏览器性能监控方式

Chrome浏览器提供了一系列强大的工具来检测和优化页面性能,其中包括但不限于以下几个主要手段:

  1. 开发者工具(DevTools)

    • Performance(性能)面板:通过录制和分析页面加载和交互过程中的性能数据,包括加载时间、CPU使用、内存占用、网络请求、渲染性能等。可以捕获并回放缓存渲染帧,分析页面加载和交互的各个阶段,找出性能瓶颈。
    • Memory(内存)面板:监视和分析页面的内存使用情况,帮助找出内存泄漏等问题。
    • Audits(审核)或Lighthouse(灯塔) :提供网页性能评估报告,给出优化建议,包括首屏加载时间、可交互时间、资源加载速度等方面的评分和改进意见。
  2. Timeline(时间线) :记录并展示页面生命周期中的所有活动,如JavaScript执行、布局渲染、绘制等,帮助了解页面何时何地发生了重排和重绘。

  3. Network(网络)面板:监视和分析所有的网络请求,包括加载时间、大小、HTTP状态码、缓存策略等,可以模拟不同的网络条件,如3G、4G、离线等。

  4. Rendering(渲染)面板:提供了布局和绘制相关的工具,例如可以显示渲染层、检查层叠上下文、分析页面合成和绘制过程。

  5. Coverage(覆盖率)工具:可以分析网页中CSS和JavaScript资源的利用率,帮助识别未使用的CSS规则和未执行的JavaScript代码。

  6. Consoles(控制台) :用于查看和过滤JavaScript日志、警告和错误信息,以及执行命令行操作。

  7. Sources(源代码)面板:可以设置断点进行JavaScript代码调试,查看内存快照等。

通过这些工具,开发者可以深入分析页面性能问题,采取针对性的优化措施,如优化资源加载、减少重排和重绘、压缩代码和资源、合理安排代码执行时机等,以提升页面加载速度和用户体验。

SEO

SEO(Search Engine Optimization)即搜索引擎优化,是一种提高网站在搜索引擎自然搜索结果中排名的技术和策略,旨在增加网站的可见度,吸引更多的高质量流量,进而提升网站的品牌曝光、用户访问量和转化率。

SEO主要分为以下几个关键方面:

  1. 关键词研究

    • 通过研究用户搜索习惯和意图,确定和选取目标关键词及长尾关键词,确保网站内容围绕这些关键词展开,从而更容易被搜索引擎匹配到相关搜索请求。
  2. 网站结构优化

    • 建立清晰的网站结构和导航,确保搜索引擎蜘蛛可以顺畅地爬取和索引所有页面。
    • 利用面包屑导航、合理的URL结构、XML sitemap等方式辅助搜索引擎理解和抓取网站内容。
  3. 内容优化

    • 创作高质量、原创、有价值的内容,满足用户需求,并且包含目标关键词。
    • 优化元标签(Meta tags),如Title(标题)、Description(描述)、Keywords(关键词,虽然现在对Google排名的影响不大,但对其他一些搜索引擎仍有意义)等,以准确传达页面主题。
    • 使用合适HTML标签,如H1-H6标题标签、strong/em强调标签等,帮助搜索引擎识别内容层次和重点。
  4. 页面加载速度优化

    • 减少页面加载时间,优化图片大小、使用CDN加速、压缩代码、启用HTTP/2或HTTP/3、启用GZIP压缩等。
    • 实现移动友好,响应式设计或AMP(Accelerated Mobile Pages)技术,确保网站在各种设备上都能快速加载和良好呈现。
  5. 链接建设

    • 内链策略:确保网站内部页面之间相互连通,通过锚文本链接指向相关页面,提高用户体验和搜索引擎对页面重要性的判断。
    • 外链策略:获得来自权威网站的高质量反向链接,这被视为投票认可,对提升网站信誉和排名有重要作用。
  6. 社交媒体和品牌提及

    • 社交媒体活动和品牌在网上的正面提及也可能间接影响SEO表现,尤其是品牌知名度和声誉的提升有助于提高用户搜索意愿和点击率。
  7. 本地搜索优化

    • 对于实体商家或服务提供商,还需要关注本地SEO,包括在Google My Business等平台上完善商业信息,获取本地客户的搜索曝光。
  8. 合规性与用户体验

    • 遵循搜索引擎发布的最佳实践和指南,避免使用黑帽SEO技术,重视网站的用户体验(UX),包括页面加载速度、可读性、导航易用性等因素。

总之,SEO是一个长期且持续的过程,涉及到网站内容、结构、代码优化、用户体验等多个维度,旨在通过不断提升网站质量和符合搜索引擎排名算法,提高网站在搜索结果中的自然排名,进而吸引流量并实现商业目标。

浏览器设备指纹

浏览器设备指纹(Browser Fingerprinting)是一种追踪和识别用户浏览器的技术,它通过收集浏览器和设备的各种独特特性,组合形成一个相对稳定的标识符,类似于人的指纹一样,可用于识别和区分不同的浏览器实例,即使用户清除了 cookies 或启用了隐私模式。

浏览器设备指纹包括但不限于以下信息:

  1. 浏览器基本信息:如浏览器类型、版本、引擎、插件列表等。
  2. 设备特性:屏幕分辨率、颜色深度、可用字体、时区、语言设置、CPU核心数、GPU信息等。
  3. 浏览器能力测试结果:如对HTML5特性的支持程度、Canvas渲染的哈希值、WebGL指纹等。
  4. 用户行为特征:如滚动条行为、鼠标移动轨迹等非硬性特征,有时也被用于丰富设备指纹。
  5. 网络信息:IP地址、浏览器报告的时区、浏览器发出的HTTP请求头信息等。

通过这些信息的组合,网站和广告服务商可以构建一个足够独特的“指纹”,即使用户在不登录的情况下也能大致识别其身份,从而实现用户追踪、广告定向投放、防止欺诈行为等功能。然而,这种方法对用户隐私造成了很大威胁,因为即便用户尝试隐匿自己的线上行为,也可能因设备指纹的独特性而被识别出来。

随着用户隐私意识的提高和技术的进步,一些现代浏览器已经开始实施反指纹技术,限制或混淆对外提供的设备信息,以增强用户的隐私保护。同时,也有一些浏览器插件和隐私工具可以帮助用户对抗设备指纹追踪。

HTTPS

HTTPS(全称 HyperText Transfer Protocol Secure)是一种网络安全协议,它在HTTP(超文本传输协议)的基础上通过SSL/TLS(安全套接字层/传输层安全)协议对通信内容进行加密,从而提供一个安全的通信通道。HTTPS 主要解决的问题包括:

  1. 数据加密:在客户端和服务器之间传输的数据会被SSL/TLS协议加密,这意味着即使数据在传输过程中被第三方截获,也不能直接解读其内容,从而保护了用户的隐私信息,如登录凭据、信用卡号、个人通信内容等。
  2. 身份验证:HTTPS不仅加密数据,还通过SSL证书对服务器的身份进行验证,确保用户访问的是预期的真实网站,而不是假冒的钓鱼网站。服务器会向客户端出示由受信任的证书颁发机构签发的SSL证书,证书中包含了服务器的身份信息,浏览器通过验证证书来确认服务器身份。
  3. 完整性校验:HTTPS协议还能确保数据在传输过程中不被篡改,通过散列算法和消息认证码(MAC)等机制来校验数据的完整性。

因此,使用HTTPS的原因主要包括:

  • 保护隐私:对敏感信息进行加密,防止中间人攻击和窃听。
  • 防止篡改:确保数据在传输过程中未经非法改动。
  • 身份验证:增强用户对网站的信任度,避免欺诈和钓鱼攻击。
  • 搜索引擎优化:现代搜索引擎倾向于优先收录和展示使用HTTPS的网站。
  • 法律合规:许多法规要求在处理用户个人信息时必须采用安全传输机制,HTTPS是满足这一要求的有效手段。

总结来说,HTTPS是构建可信、安全互联网的重要基石,广泛应用于电子商务、银行、社交网络等多个领域,以保障用户数据安全和隐私权益。

ClickJacking

ClickJacking(点击劫持)是一种网络攻击技术,它通过覆盖一个透明或者不可见的界面,诱骗用户在不知情的情况下点击实际位于该界面上层的元素,使得用户在原本无意的地方触发了点击事件。这种攻击方式通常用来盗取用户信息、控制用户账户、传播恶意软件或者进行其他未授权操作。

ClickJacking攻击的工作原理:

  1. 攻击者创建一个网页,在该网页中嵌入一个iframe指向目标网站的某个功能页面(如“赞”按钮、删除按钮等)。
  2. 攻击者在自己的网页上放置一些吸引用户注意力的内容,同时将iframe完全透明化或者与背景融合,使得用户无法察觉底层的目标页面元素。
  3. 当用户在攻击者页面上进行操作时,实际上可能是在点击经过精心布局的iframe内的功能按钮,这样就完成了攻击者预设的动作,而用户对此毫无感知。

防范ClickJacking的主要措施有:

  • X-Frame-Options Header:服务器端可以设置X-Frame-Options响应头来限制页面是否允许在frame或iframe中展示,可以选择deny(不允许任何页面嵌入)、sameorigin(只允许同源页面嵌入)或allow-from指定来源。
  • Content Security Policy (CSP) :通过配置Content-Security-Policy头部,可以限制资源加载,其中包括frame-src或child-src指令来限制哪些页面可以嵌入iframe内。
  • iframe 检测及遮罩层:在网页中加入JavaScript代码检测当前页面是否在iframe中加载,并在必要时添加一层遮罩层阻止用户交互。
  • 用户交互设计改进:对于敏感操作增加确认步骤,例如二次确认对话框,以及对涉及安全的关键操作采用非iframe形式展现。

总之,ClickJacking是一种利用视觉欺骗和页面嵌套技术的攻击方式,网站开发者应当采取合适的安全策略来预防此类攻击的发生。

CSP (Content Security Policy)

Content Security Policy(CSP)是一种强大的安全策略机制,用于定义一个web应用允许加载哪些外部资源,包括脚本、样式表、图片、字体等。通过实施CSP,网站管理员可以更加精确地控制浏览器对内容的加载行为,从而有效地抵御跨站脚本攻击(XSS)、恶意资源注入等安全威胁。

CSP的基本工作原理是通过HTTP响应头或者HTML meta标签的形式,向浏览器提供一个政策声明,该声明规定了哪些源(source)是可以信赖的,浏览器会根据这些策略限制非可信源的资源加载。CSP策略包含一系列指令,每条指令定义了特定类型的资源允许加载的源列表。

例如,以下是一些CSP指令的例子:

  1. script-src: 控制哪些源可以执行脚本。例如,script-src 'self' https://trustedscripts.com;表示只允许执行来自当前源和https://trustedscripts.com的脚本。
  2. style-src: 控制哪些源可以加载CSS样式。例如,style-src 'self' 'unsafe-inline'; 允许加载当前源的内联样式和外部样式表。
  3. img-src: 控制图片加载源。例如,img-src data: https://*.trustedimages.com;允许加载data URI和来自.trustedimages.com子域名的图片。
  4. connect-src: 控制哪些源可以发起网络连接(例如XMLHttpRequest、WebSockets等)。
  5. object-srcmedia-srcfont-src等类似指令,分别控制插件、多媒体资源和字体的加载源。
  6. base-uri: 控制页面的基础URI(即页面中标签所引用的地址)。
  7. default-src: 如果没有指定具体的资源类型指令,那么这个默认指令将作为所有未明确指定类型的资源的默认策略。
  8. report-uri 或 report-to: 指定报告策略违反情况的URL,浏览器会在发生策略违规时向指定地址发送报告,以便开发者监控和修复潜在的安全问题。

在实施CSP时需要注意:

  • CSP策略是增强安全的一个有力工具,但并非万无一失,仍需结合其他安全措施一同使用。
  • 使用CSP时要避免过于严格的策略导致网站功能异常,同时也应定期审查和更新策略,以适应不断变化的安全需求和网站架构。
  • CSP策略中的 'unsafe-inline' 和 'unsafe-eval' 关键字可以让浏览器执行内联脚本和eval()函数,但这会削弱CSP的部分保护效果,应尽量避免使用。

总之,Content Security Policy是现代Web安全的重要组成部分,合理地配置和执行CSP可以帮助开发者大幅提升网站的安全性,对抗常见的注入攻击和资源篡改风险。

富文本编辑器

前端富文本编辑器(Frontend Rich Text Editors)是Web开发中常用的一种组件,允许用户在网页上进行类似于桌面文字处理软件一样的复杂文本编辑,包括格式化文本、插入图片、链接、表格等操作。以下是一些流行的前端富文本编辑器:

  1. wangEditor

    • 基于JavaScript和CSS开发的轻量级富文本编辑器,以其简洁的设计和易于使用的API受到开发者欢迎,同时支持多种浏览器,开源并免费使用。
  2. TinyMCE

    • 一款广泛应用于各类Web项目的成熟富文本编辑器,提供了丰富的插件和高度定制化能力,确保了良好的用户体验和广泛的浏览器兼容性。
  3. 百度ueditor

    • 由百度研发的一款所见即所得的富文本编辑器,具有良好的定制性和本地化服务,同样开源并且基于MIT协议授权。
  4. KindEditor

    • 开源的在线HTML编辑器,适用于将textarea转换为可视化富文本编辑框,提供多种实用功能。
  5. Syncfusion富文本编辑器

    • 一款支持HTML和Markdown格式的编辑器,具备高度可配置的工具栏、内联编辑模式等功能,并能方便地插入和编辑表格、图像等内容。