http前端精选面试题

309 阅读1小时+

在发送 http 请求报文时,host 是必要的吗

在发送 HTTP 请求报文时,Host 头字段是必要的(具体取决于 HTTP 协议版本和应用场景)。以下是详细解释:


1. HTTP/1.1 及更高版本:必须包含 Host 头

  • RFC 规范要求:根据 HTTP/1.1 协议(RFC 7230),客户端必须在请求中包含 Host 头字段,否则服务器会返回 400 Bad Request 错误。
  • 用途Host服务器通过此字段区分不同网站(尤其是当单个 IP 托管多个域名时,即“虚拟主机”)。例如:
    GET /index.html HTTP/1.1
    Host: www.example.com  # 服务器通过此字段区分不同网站
    
  • 示例场景
    • 如果通过 IP 直接访问服务器(如 http://192.168.1.1),仍需显式指定 Host 头。
    • 若省略 Host 头,服务器无法确定客户端请求的是哪个域名的资源

2. HTTP/1.0:Host 头非必需

  • 在早期的 HTTP/1.0 中,Host 头不是强制要求的,因为当时单 IP 对应单域名的场景更常见。
  • 现状:由于 HTTP/1.0 已过时,现代服务器和客户端普遍遵循 HTTP/1.1 或更高版本规范。

实际开发建议:始终在 HTTP/1.1 及以上版本的请求中包含 Host 头,以确保兼容性和正确路由。

http1.1与http2有什么不同 ⭐️⭐️ (重点)

http1.1

  • 持久连接:HTTP1.0 中,每次请求 - 响应完成后,连接就会关闭,而 HTTP1.1 支持持久连接,只要客户端/服务端中任意一端没有明确指出断开TCP连接,就一直保持连接。减少了建立和关闭连接的开销,提高了传输效率
  • 管线化在一次 TCP 连接中可以传输多个 HTTP 请求和响应,而不用等待前一个请求的响应回来再发下一个,提高了传输效率 。但服务器仍需按顺序处理和响应请求。比如在浏览网页加载多个资源时,客户端能连续发出资源请求。
  • 分块传输编码:当服务器不知道响应数据的长度时,可使用分块传输编码,将数据分成多个块进行传输,增强了传输的灵活性。断点续传
  • 缓存处理改进:引入更多缓存相关的指令,如Cache-Control,能更精准地控制页面缓存,提高缓存的有效性和安全性。
  • Host 头字段支持在同一个 IP 地址端口号上部署多个网站,通过Host头字段来区分不同的站点

http2

  • 1、二进制传输
  • 2、多路复用
  • 3、头部压缩
  • 4、服务器推送
  • 5、 流优先级
  • 6、更安全

HTTP/2(2015 年发布) 在 HTTP/1.1(1997 年发布)的基础上进行了多项改进,主要目标是提升性能、降低延迟


1. 二进制协议 vs 文本协议

  • HTTP/1.1

    • 文本格式请求和响应以纯文本(如 GET /index.html HTTP/1.1)传输,解析复杂且易出错。
  • HTTP/2

    • 二进制分帧:将数据分解为更小的二进制(如 HEADERS 帧、DATA 帧),传输效率更高,解析更简单。

2. 多路复用(Multiplexing)

  • HTTP/1.1

    • 队头阻塞(Head-of-Line Blocking):每个 TCP 连接在同一时间只能处理一个请求(虽然浏览器支持 6-8 个并行连接,但资源竞争仍会导致延迟)。
    • 低效并行大量请求需要多个 TCP 连接,增加了资源开销
  • HTTP/2

    • 单连接多流:通过二进制分帧层,允许在 单个 TCP 连接上并行传输多个请求和响应(称为“流”)。
    • 消除队头阻塞请求和响应 交替传输,互不影响。

3. 头部压缩(Header Compression)

  • HTTP/1.1

    • 重复传输头部:每次请求都携带完整的头部(如 Cookie、User-Agent),冗余数据浪费带宽。
  • HTTP/2

    • HPACK 压缩算法:使用静态字典(预定义常用字段)和动态字典(记录本次连接的字段)压缩头部,减少传输体积。
    • 典型压缩率:头部大小可减少 50%~90%

4. 服务器推送(Server Push)

  • HTTP/1.1

    • 被动响应:服务器只能返回客户端显式请求的资源
  • HTTP/2

    • 主动推送:服务器可预测客户端需求,提前推送相关资源(如 CSS、JS 文件),减少往返延迟
    • 示例:当客户端请求 index.html 时,服务器可同时推送 style.css

5. 流优先级(Stream Prioritization)

  • HTTP/1.1

    • 无优先级控制资源加载顺序由浏览器猜测,可能导致关键资源(如 CSS)延迟加载。
  • HTTP/2

    • 优先级标记客户端可为每个流设置权重和依赖关系,确保关键资源优先传输(如优先加载 HTML 骨架,再加载图片)。

6. 安全性(Security)

  • HTTP/1.1

    • 明文传输:默认不加密,需通过 HTTPS(HTTP over TLS)实现安全通信。
  • HTTP/2

    • 不强制加密协议本身未要求加密,但主流浏览器(如 Chrome、Firefox)仅支持基于 HTTPS 的 HTTP/2。
    • 实际强制加密:实践中 HTTP/2 几乎总是与 TLS 结合使用。

实际影响

  1. 加载速度提升:HTTP/2 显著减少延迟,尤其对高延迟网络(如移动端)效果明显。
  2. 资源利用率优化:减少 TCP 连接数和头部开销,降低服务器压力。
  3. 兼容性:HTTP/2 完全兼容 HTTP/1.1 的语义(如方法、状态码),无需修改应用层逻辑。

注意事项

  • 旧设备支持:部分老旧代理或防火墙可能不支持 HTTP/2 的二进制协议,需降级到 HTTP/1.1。
  • 服务器配置:需 Web 服务器(如 Nginx、Apache)和 CDN 支持 HTTP/2。
  • HTTPS 成本强制加密需配置 TLS 证书,可能增加运维成本

总结:HTTP/2 通过多路复用、头部压缩、服务器推送等机制,解决了 HTTP/1.1 的性能瓶颈,是构建现代高性能 Web 应用的基石。

简单讲解一下http2的多路复用 ⭐️

即单个 TCP 连接上并行传输多个请求和响应 HTTP/2 的多路复用(Multiplexing) ,目的是解决 HTTP/1.x 的队头阻塞问题,显著提升网络传输效率。

1. HTTP/1.1 的痛点:队头阻塞

在 HTTP/1.1 中:

  • 客户端和服务器通过一个 TCP 连接 按顺序发送请求和响应
  • 如果某个请求耗时较长(比如下载一个大文件),后续请求必须排队等待,这就是队头阻塞
  • 虽然可以通过并发多个 TCP 连接缓解问题(比如浏览器默认开6个连接),但会消耗更多资源,且难以彻底解决。

2. HTTP/2 的解决方案:多路复用

HTTP/2 允许在同一个 TCP 连接上,并行传输多个请求和响应,且彼此互不阻塞。实现原理如下:

  • 二进制分帧层:HTTP/2 将请求和响应拆分为更小的二进制帧(Frame)每个帧 携带一个唯一标识(Stream ID)表示它属于哪个请求/响应
  • 并行传输:所有帧通过同一个 TCP 连接发送,不同 Stream ID 的帧可以交替传输,服务器和客户端会根据 Stream ID 重新组装成完整的请求/响应
举个例子:

假设浏览器需要加载一个页面,包含 HTML、CSS、图片等资源:

  • HTTP/1.1需要按顺序逐个请求,或者开多个 TCP 连接并行请求(资源浪费)。
  • HTTP/2:在同一个连接中,所有资源请求的帧混合传输,无需等待前一个完成。

3. 多路复用的优势

  1. 消除队头阻塞:慢请求不会阻塞其他请求。
  2. 减少连接数:无需创建多个 TCP 连接,降低服务器和客户端资源消耗。

4. 对比 HTTP/1.1 的管道化(Pipelining)

HTTP/1.1 曾尝试通过管道化(一次性发送多个请求)优化性能,但存在严重缺陷:

  • 响应必须按请求顺序返回(依然有队头阻塞)。
  • 部分服务器不支持或实现不完善。

总结

HTTP/2 的多路复用通过 二进制分帧流标识(Stream ID),实现了同一连接上的高效并发,解决了 HTTP/1.x 的性能瓶颈,是现代化 Web 高效传输的基石。

介绍一下http2.0

什么是HTTP2.0

1、是HTTP协议的第二个主要版本,主要基于SPDY协议,大幅度提高了web性能,降低延迟。

SPDY是Speedy的昵音,意为“更快”。它是Google开发的基于TCP协议的应用层协议。目标是优化HTTP协议的性能,通过压缩、多路复用和优先级等技术,缩短网页的加载时间并提高安全性。SPDY协议的核心思想是尽量减少TCP连接数。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强

HTTP2.0特点

1、二进制传输

文本的表现形式有多样性,健壮性考虑,HTTP2.0中所有加强性能的核心是二进制传输,在HTTP1.x中,我们是通过文本的方式传输数据

基于文本的方式传输数据存在很多缺陷,文本的表现形式有多样性,因此要做到健壮性考虑的场景必然有很多,但是二进制则不同,只有0和1的组合,因此选择了二进制传输,实现方便且健壮

在HTTP2.0中引入了新的编码机制,所有传输的数据都会被分割,并采用二进制格式编码。 为了保证HTTP不受影响,那就需要在应用层(HTTP2.0)和传输层(TCP or UDP)之间增加一个二进制分帧层。在二进制分帧层上,HTTP2.0会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码,其中HTTP1.x的首部信息会被封装到Headers帧,而Request Body则封装到Data帧。

2、多路复用

即单个 TCP 连接上并行传输多个请求和响应 在HTTP1.0中,我们经常会使用到雪碧图、使用多个域名等方式来进行优化,都是因为浏览器限制了同一个域名下的请求数量,当页面需要请求很多资源的时候,队头阻塞(Head of line blocking)会导致在达到最大请求时,资源需要等待其他资源请求完成后才能继续发送。 HTTP2.0中,有两个概念非常重要:帧(frame)和流(stream)。 帧是最小的数据单位,每个帧会标识出该帧属于哪个流,流是多个帧组成的数据流。 所谓多路复用,即在一个TCP连接中存在多个流,即可以同时发送多个请求,对端可以通过帧中的表示知道该帧属于哪个请求。在客户端,这些帧乱序发送,到对端后再根据每个帧首部的流标识符重新组装。通过该技术,可以避免HTTP旧版本的队头阻塞问题,极大提高传输性能。

3、Header压缩

使用文本的形式传输header,在header中携带cookie的话,开销大

在HTTP1.1中,我们使用文本的形式传输header,在header中携带cookie的话,每次都需要重复传输几百到几千的字节,这着实是一笔不小的开销。 在HTTP2.0中,我们使用了HPACK(HTTP2头部压缩算法)压缩格式对传输的header进行编码,减少了header的大小。并在两端维护了索引表,用于记录出现过的header,后面在传输过程中就可以传输已经记录过的header的键名,对端收到数据后就可以通过键名找到对应的值。

4、服务器Push

在HTTP2.0中,服务端可以在客户端某个请求后,主动推送其他资源。 可以想象一下,某些资源客户端是一定会请求的,这时就可以采取服务端push的技术,提前给客户端推送必要的资源,就可以相对减少一点延迟时间。在浏览器兼容的情况下也可以使用prefetch。

5、更安全

HTTP2.0使用了tls的拓展ALPN做为协议升级,除此之外,HTTP2.0对tls的安全性做了近一步加强,通过黑名单机制禁用了几百种不再安全的加密算法。

随着 http2 的发展,前端性能优化中的哪些传统方案可以被替代

随着 HTTP/2 的普及,其核心特性(如多路复用、二进制分帧、服务器推送等)显著改变了前端性能优化的策略。以下是一些可被替代的传统优化方案及其替代思路:

1. 资源合并(文件合并与雪碧图)

  • 传统方案:合并多个 CSS/JS 文件为单个文件,或使用雪碧图(CSS Sprites)减少 HTTP 请求次数。
  • HTTP/2 的替代
    • 多路复用:小文件通过单一连接并行传输,合并文件反而可能降低缓存效率(如某部分内容变更需重新下载整个文件)。
    • 雪碧图:HTTP/2 下,独立图片请求更高效,雪碧图维护成本高且不利于按需加载,可改用单独图片或 WebP/AVIF 格式优化体积。

2. 内联资源(如 Base64 图片、行内 CSS/JS)

  • 传统方案将资源(如图片转为 Base64、CSS/JS 内联到 HTML)以减少请求次数
  • HTTP/2 的替代HTTP/2 对小文件请求更高效,内联资源会增加 HTML 体积,影响首屏渲染速度和缓存策略。建议将资源外链,利用 HTTP/2 的多路复用特性。

3. 管线化(HTTP Pipelining)优化

  • 传统方案:HTTP/1.1 的管道化允许在同一个连接上发送多个请求,但响应必须按顺序返回,实际应用受限且易受队头阻塞影响。
  • HTTP/2 的替代HTTP/2 的二进制分帧和流(Stream)机制天然支持乱序传输,彻底解决队头阻塞问题,无需手动优化请求顺序。

4. 手动资源预加载

  • 传统方案:通过 <link rel="preload"> 或 JavaScript 预加载关键资源。
  • HTTP/2 的替代:利用 服务器推送(Server Push)服务器可主动推送与当前请求相关的资源(如 CSS、JS),减少客户端主动请求的延迟。例如,Nginx 可通过 Link 头部实现推送。

总结

HTTP/2 通过协议层的改进,简化了许多 HTTP/1.1 时代的“妥协式”优化方案。开发者应摒弃过度合并、分片等传统手段,转而利用多路复用、服务器推送等特性,结合现代前端工程化工具(如 Webpack 按需加载、Vite 原生 ESM)实现更高效的性能优化。

HTTP/2 时代的新优化方向

  1. 优先级与流量控制通过设置资源优先级(如 CSS > 图片),确保关键资源优先加载
  2. Server Push 的合理使用避免过度推送导致带宽浪费,需结合实际业务场景动态调整。
  3. TLS 优化:HTTP/2 通常与 HTTPS 绑定,需优化 TLS 握手(如 Session Resumption、TLS 1.3)以减少延迟。

http1.1是如何复用tcp连接

在 HTTP/1.1 中,TCP 连接的复用是通过持久连接实现的


1. HTTP/1.1 的持久连接(Keep-Alive)

  • 默认行为HTTP/1.1 默认启用持久连接无需显式添加 Connection: keep-alive 头字段)。
  • 工作原理
    • 客户端和服务器建立一次 TCP 连接后,可以在该连接上发送多个 HTTP 请求/响应按顺序处理)。
    • 连接不会在每次请求后立即关闭,而是**保持打开状态直到超时或主动关闭**。
  • 示例流程
    # 第一次请求
    GET /page1.html HTTP/1.1
    Host: example.com
    
    # 服务器响应后,同一 TCP 连接继续复用:
    GET /page2.html HTTP/1.1
    Host: example.com
    

HTTP/3的核心改进是什么?

  • 基于QUIC协议 :在UDP上实现可靠传输,解决TCP队头阻塞。
  • 快速握手 :0-RTT或1-RTT建立连接(减少延迟)。
  • 连接迁移 :网络切换时(如WiFi转4G)保持连接。

http2.0/http3.0

常见考点

在前端面试中,HTTP/2 与 HTTP/3 的考察,主要围绕它们对页面加载性能的影响、核心特性对比、底层协议差异以及使用中的优劣权衡。

一、背景与版本演进

协议版本年份核心变化
HTTP/1.11997长连接(Keep-Alive)、管道化(但有队头阻塞)
HTTP/22015二进制帧、多路复用、头部压缩、服务端推送
HTTP/32022基于 QUIC 替代 TCP,进一步解决队头阻塞,提升可靠性

二、HTTP/1.1 vs HTTP/2 vs HTTP/3 对比

特性HTTP/1.1HTTP/2HTTP/3
传输协议TCPTCPQUIC(基于 UDP)
多路复用❌ 队头阻塞✅ 同一连接并行传输✅ 无队头阻塞
首部压缩❌ 无压缩✅ HPACK✅ QPACK(防止队头阻塞)
Server Push❌ 不支持✅ 支持❌ 已废弃(实践效果差)
建连速度普通 TCP + TLSTCP + TLS✅ 快速握手(1-RTT)
丢包处理影响所有流影响所有流✅ 仅影响单一流
中间设备兼容性⚠️ UDP 可能被阻断

四、HTTP/3 的面试考察点

1. QUIC 协议(核心考点)

  • 基于 UDP支持多路复用,无需三次握手
  • 加密集成在协议中(类似 TLS 1.3),连接建立更快
  • 无队头阻塞丢包不会影响所有请求,只影响对应流

2. QPACK 头部压缩算法

  • 类似 HPACK,但解决了在多路复用中可能造成阻塞的问题

3. 快速恢复连接

  • QUIC 支持 0-RTT 连接恢复,提升访问速度(尤其移动网络

4. 防中间人攻击

  • QUIC 所有内容默认加密,提升安全性
  • 中间代理设备无法篡改请求内容

5. 使用上的挑战

  • 部分网络设备不支持 UDP 或限制端口
  • 浏览器和 CDN 需明确支持 HTTP/3(如 Chrome、Cloudflare 支持)

五、面试常见问题示例

问题涉及考点
HTTP/2 和 HTTP/1.1 有哪些不同?多路复用、帧机制、压缩、Server Push
HTTP/3 为什么使用 QUIC?解决 TCP 队头阻塞、连接快、抗丢包
QUIC 相比 TCP 有什么优势?基于 UDP、多路复用、低延迟连接
为什么说 HTTP/2 仍然存在队头阻塞?底层仍基于 TCP,TCP 丢包影响整条流
HTTP/3 是否取代 HTTP/2?正在推广中,但需服务端、客户端、CDN 三方支持
Server Push 有什么问题?资源浪费、缓存难控、已废弃

六、实际使用和优化建议(工程落地)

  • 启用 HTTP/2/3 需后端或 CDN 支持(例如在 Nginx、Cloudflare 开启)
  • 前端不需要做太多改动,但要合理使用 preload 代替 server push
  • 对图片、CSS、JS 等静态资源分发,HTTP/2 提升明显
  • 对动态资源或高延迟网络访问,HTTP/3 的优势更大

七、总结

  • 为什么 HTTP/2 引入多路复用?→ 解决 HTTP/1.1 队头阻塞
  • 为什么 HTTP/3 不再使用 TCP?→ TCP 层面的队头阻塞无法解决
  • 为什么 QUIC 比 TCP 快?→ 更快建连、单流丢包不影响整体
  • 为什么 Server Push 被废弃?→ 实际效果不佳,控制困难

关联面试题

为什么说 HTTP/2 仍然存在队头阻塞?

HTTP/2 解决了 HTTP/1.1 的队头阻塞(请求级阻塞) ,但仍存在 TCP 层的队头阻塞,核心原因如下:

  1. HTTP/2 的改进它基于单个 TCP 连接实现多路复用,多个请求 / 响应可在同一连接上并行传输,不会因为一个请求阻塞导致后续请求排队,解决了 HTTP 应用层的队头阻塞。
  2. TCP 层的队头阻塞无法避免TCP 是可靠的字节流协议,数据传输以有序报文段的形式进行。如果某一段报文丢失或出错,即使后续报文已到达,也必须等待丢失的报文重传并确认后,才能将数据交给应用层(HTTP/2)。此时,HTTP/2 多路复用的所有流都会被阻塞,这就是 TCP 层的队头阻塞

简单说:HTTP/2 解决了应用层的队头阻塞,但绕不开 TCP 协议本身的有序传输特性,因此仍存在底层的队头阻塞

http2.0 服务端推送常见考点

HTTP/2 的服务端推送(Server Push)是一个重要但实际使用率较低的特性。它允许服务器在客户端还未明确请求资源时,主动将资源“推送”给客户端,用于提前加载关键资源以加快页面渲染。

虽然 HTTP/3 取消了该功能,但面试中仍会从“机制原理 + 使用场景 + 弊端与替代方案”多个角度进行考察。

一、基础原理考察

1. 什么是 HTTP/2 的 Server Push?

  • 客户端发起一个主请求(如 HTML 页面)时,服务器可以在响应之前或同时,主动推送其它关联资源(如 CSS/JS)。
  • 客户端无需显式请求这些资源,它会缓存或使用服务端推送的内容。

2. 工作机制

  • 浏览器发起请求 → 服务器通过 PUSH_PROMISE 帧声明要推送哪些资源
  • 客户端接收到声明后,可选择接受或拒绝(缓存中已有则拒绝)
  • 服务器随后发送资源 → 客户端使用或缓存

二、使用场景考察

  • 页面关键资源预加载:如首页 HTML 加载时提前推送 CSS/JS
  • 提升首屏加载速度:配合缓存策略使用,在访问频繁页面中生效显著
  • 避免额外 RTT(请求-响应延迟)

三、配置与实现考察

1. Nginx 示例:

http2_push /styles.css;
http2_push /main.js;

2. Express 示例(使用 Link 头):

res.set('Link', '</style.css>; rel=preload; as=style');

3. HTTP 响应头方式:

Link: </styles.css>; rel=preload; as=style

注意:这种方式只在支持 HTTP/2 Server Push 的服务端生效。

四、常见面试考点

问题回答要点
HTTP/2 的 Server Push 原理?主动发送 PUSH_PROMISE,减少 RTT,预加载资源
与浏览器 preload 的区别?preload 是客户端主动告知,Server Push 是服务端主动
Server Push 如何实现?使用 Link 头或服务器配置,依赖 HTTP/2
Server Push 有哪些缺陷?资源可能已缓存、浪费带宽、无法精准控制推送时机
Server Push 为什么在 HTTP/3 中被废弃?使用率低、不稳定、难以优化资源调度
如何替代 Server Push?使用 preload、prefetch、Service Worker 缓存等

五、缺陷与注意点考察

  • 缓存浪费问题:如果客户端已经缓存资源,服务端仍然推送 → 浪费带宽
  • 调度不可控:无法像 JS preload 那样设置优先级、资源时机
  • 对 CDN 不友好:CDN 无法判断是否应推送资源
  • 浏览器支持差异:部分浏览器已不再积极支持该特性
  • 现代替代方案更可控:如 <link rel="preload">、lazy loading

http优化策略 ⭐️⭐️重点

  • 一、减少请求数量
  • 二、减少响应体积
  • 三、提升协议层

以下是针对 HTTP 协议性能优化的常见策略,从协议特性到工程实践的全方位总结:


一、减少请求数量

  1. 资源合并

    • CSS/JS 文件合并:减少 HTTP 请求次数(适用于 HTTP/1.1,HTTP/2 中无需过度合并)。
    • 雪碧图(CSS Sprites):将多个小图标合并为一张大图,通过 background-position 定位。
  2. 缓存策略优化

    • 强缓存(Cache-Control, Expires)与协商缓存(ETag, Last-Modified)合理配置,避免重复请求。

二、减少响应体积

  1. 压缩算法

    • Gzip/Brotli 压缩:对文本类资源(HTML/CSS/JS)启用压缩,减少传输体积。
    • 图片优化:使用 WebP/AVIF 格式,或通过工具压缩 JPEG/PNG。
  2. Tree Shaking & 代码分割

    • 前端构建时移除未使用的代码,按需加载模块(如 Webpack 的 splitChunks)。

三、协议层升级

  1. 多路复用

    • 单个 TCP 连接上并行传输多个请求和响应
  2. 服务器推送

    • 服务器主动推送关键资源(如 CSS/JS),减少客户端请求延迟。
  3. 0-RTT 握手(HTTP/3)

    • QUIC 协议支持快速恢复会话,减少 TLS 握手时间

四、其他

  1. CDN 加速

    • 将静态资源分发到全球边缘节点,缩短用户与资源的物理距离
  2. 预加载与预连接

    • <link rel="preload">:提前加载关键资源。
    • <link rel="preconnect">提前建立 DNS 查询、TCP 握手等连接步骤。

cookie和token的运用机制 ⭐️⭐️ (重点)

  • 1、Cookie + Session:传统方案,依赖服务器存储,适合单体应用
  • 2、Token(如 JWT):无状态方案,适合分布式或前后端分离系统
  • 无论哪种方式,本质都是通过 客户端携带标识 + 服务器验证标识 来实现状态保持。

HTTP 协议本身是无状态的,这意味着每次请求和响应之间是独立的,服务器默认不会记录之前的请求信息。但通过以下技术手段,可以实现用户登录状态的保持:


1. Cookie(客户端存储)

  • 核心机制:服务器通过响应头 Set-Cookie 向客户端(浏览器)下发一个唯一标识(如 Session ID),浏览器后续请求会自动携带该 Cookie
  • 流程
    1. 用户登录时,服务器验证账号密码后生成一个唯一 Session ID,通过 Set-Cookie 返回给浏览器。
    2. 浏览器后续每次请求都会自动在请求头 Cookie 中携带此 Session ID
    3. 服务器通过 Session ID 识别用户身份。
  • 安全性:Cookie 需设置 HttpOnly(防XSS)、Secure(仅 HTTPS 传输)、SameSite(防CSRF)等属性。

2. Session(服务器存储)

  • 核心机制Session ID 对应服务器端的用户数据(如用户ID、权限等)。
  • 流程
    1. 用户登录后,服务器在内存或数据库中创建 Session 数据,关联一个 Session ID
    2. 服务器将 Session ID 通过 Cookie 返回给客户端。
    3. 后续请求中,服务器通过 Session ID 查找对应的 Session 数据,验证用户身份。
  • 缺点:服务器需存储 Session 数据,高并发或分布式场景下需额外处理(如 Redis 集中存储)

3. Token(无状态令牌)

  • 核心机制:用户信息加密后直接存储在客户端(如 JWT)。
  • 流程
    1. 用户登录后,服务器生成一个加密的 Token(如 JWT),包含用户ID、过期时间等信息。
    2. Token 通过响应体返回给客户端 (可存储在 LocalStorage 或 Cookie)
    3. 客户端后续请求在 Authorization 请求头中携带 Token
    4. 服务器解密 Token 直接验证用户身份,无需存储会话数据
  • 优点天然支持分布式系统,服务器无需维护 Session 状态
  • 缺点:Token 一旦泄露可能被滥用,需设置短期有效期

安全问题

  • Cookie 劫持:通过 HTTPS 加密传输、设置 Secure 属性防御。
  • XSS 攻击:设置 HttpOnly 防止 JavaScript 窃取 Cookie。
  • CSRF 攻击:使用 SameSite Cookie、CSRF Token 防御。
  • Token 泄露:JWT 需设置合理有效期,敏感操作需二次验证

cookie放哪里,cookie能做的事情和存在的价值

cookie是存在浏览器上的一小段数据,来解决 HTTP无状态机制问题,比如记录某页面关闭或者刷新后仍需要记录的信息

属性

  • cookie可以使用js在浏览器直接设置,也可以在服务器端使用HTTP协议规定的set-cookie来设置。
  • 一般cookie的容量为4k左右。
  • document.cookie查看当前浏览网站的cookie

运用

  • 会话状态管理(如用户登录状态、购物车、游戏分数、其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题色等)
  • 精准广告(平常浏览网页时有时会推出商品刚好是你最近浏览过,买过的类似东西,这些是通过cookie记录的。)

Cookie 的重点考察点

1. Cookie 属性字段

字段说明
name=value键值对数据
domain指定允许访问的域(如 .example.com
path限制 Cookie 生效路径
expires / max-age控制过期时间
secure仅 HTTPS 才发送
HttpOnlyJavaScript 无法读取,提高安全性
SameSite防止跨站请求伪造(CSRF)攻击

2. Cookie 设置方式

  • 后端设置(Set-Cookie 响应头)
  • 前端设置(document.cookie = "key=value",受限制)

3. Cookie 的跨域规则

  • 默认只发送到设置域及其子域
  • 跨域访问需使用 Access-Control-Allow-Credentials: true 且 withCredentials = true

三、Session 的重点考察点

1. Session 原理

  • 每个客户端分配一个唯一的 sessionId
  • 客户端通过 Cookie(默认名如 JSESSIONID)将 ID 发送给服务端
  • 服务端用 sessionId 找到对应的状态数据(如用户信息)

2. 存储方式

方式说明
内存快速,但不适合分布式(重启丢失)
文件系统简单可靠,性能一般
数据库/Redis支持持久化和分布式,性能好

3. 安全风险

  • Session Fixation:攻击者预设 sessionId 引导用户登录

  • Session 劫持:中间人截获 sessionId

  • 解决方式:

    • 登录成功后重置 sessionId
    • 配合 HTTPS、防止 sessionId 泄露

四、Session 与 Cookie 配合使用

  • Session 通常依赖 Cookie 来传递 sessionId
  • Cookie 负责持久化保存 ID,Session 负责保存服务端用户状态
  • 无 Cookie 时(如某些小程序、无状态 API),可用 token(如 JWT)替代

五、延伸考点:Token 与 Session 对比

对比点SessionToken(如 JWT)
存储位置服务端客户端(通常存在 Cookie 或 LocalStorage)
状态管理有状态无状态
分布式支持一般不友好天然支持
安全性不易伪造,但易劫持签名机制防篡改,失效控制难
实现复杂度简单略复杂(涉及签名/验证)

六、常见面试问题示例

问题涉及考点
Cookie 与 Session 的区别?存储位置、状态管理、安全性
Cookie 有哪些关键属性?如何防止被窃取?HttpOnly、Secure、SameSite
Session 是如何实现的?和 Cookie 有什么关系?sessionId、状态记录
Cookie 为什么有大小限制?Cookie 会随每一次 HTTP 请求(包括静态资源请求)自动携带,若 Cookie 体积过大,会显著增加请求头大小,拖慢传输速度、占用带宽,尤其对高并发场景影响明显。
前端如何设置 Cookie?document.cookie 注意 path 和 domain
Session 是如何在分布式架构中管理的?使用 Redis、数据库共享
如何防止 Session Fixation?登录后更换 sessionId
使用 token 和 session 管理登录有什么差别?状态 vs 无状态,扩展性 vs 安全控制

cookie和token都存放在header里面,为什么只劫持前者

  • Cookie 更易被劫持:主要因其自动携带特性历史遗留的配置疏漏(如未设置 HttpOnly/Secure/SameSite)。
  • Token 相对安全:因手动管理、无自动携带逻辑,但需开发者主动实现安全措施(如 HTTPS、短期 Token)。
  • 核心原则:无论是 Cookie 还是 Token,安全性取决于配置和实现,而非技术本身。

在 HTTP 协议中,Cookie 和 Token 虽然都通过 Header 传递,但劫持难度和常见攻击方式不同。以下是关键原因:


1. 自动携带机制不同

  • Cookie
    • 浏览器会自动在所有符合路径和域规则的请求中携带 Cookie(即使存在跨站风险),例如:
      GET /profile HTTP/1.1
      Cookie: session_id=abc123
      
    • 攻击面广攻击者可通过 XSS、中间人劫持、CSRF 等方式窃取或滥用 Cookie。
  • Token
    • 通常由开发者手动添加到请求头(如 Authorization: Bearer <token>),不会自动携带
    • 攻击面窄需明确劫持 Token 并构造请求,且默认不参与跨站请求。

2. 安全防护机制差异

  • Cookie 的防护依赖配置
    • 若未设置 HttpOnly,可通过 XSS 直接读取 Cookie。
    • 若未设置 SecureCookie 会通过 HTTP 明文传输
    • 若未设置 SameSite,可能被 CSRF 攻击利用(现代浏览器默认 SameSite=Lax)。
  • Token 的防护更主动
    • Token 通常配合 HTTPS 加密传输,且无自动携带逻辑
    • 若使用短期 Token(如 JWT 设置短有效期),即使泄露危害也有限。
    • JWT 可以安全地在各方之间传输信息。由于 JWT 可以被签名,接收方可以验证 JWT 的完整性和真实性,确保信息在传输过程中没有被篡改。例如,在不同服务之间传递用户信息时可以使用 JWT

cookie和session有哪些方面的区别 ⭐️

对比维度CookieSession
存储位置客户端(浏览器)服务端(内存、数据库等)
本质一段 键值对文本信息一个 服务端维护的状态标识
生命周期默认会话级,支持设置过期时间一般是浏览器关闭或超时后销毁
大小限制单个域名下最多 4KB理论不限,但受服务端资源限制
安全性容易被劫持、伪造,依赖 HTTPS 保护相对安全,但需防止 Session Fixation
使用场景状态保持、轻量存储、前后端身份标识登录认证、权限控制、用户状态管理

性能影响

  • Cookie:每次客户端向服务器发送请求时,都会在请求头中携带该域名下的所有 Cookie 信息,这会增加请求的大小,尤其是在 Cookie 数量较多或数据较大的情况下,会对网络性能产生一定的影响。
  • Session:客户端只需要在请求头中携带会话 ID,而会话数据存储在服务器端,因此请求的大小相对较小,对网络性能的影响也较小。但是,服务器需要管理和维护大量的会话数据,会占用一定的服务器资源。

有效期

  • Cookie:可以设置不同的有效期。会话级 Cookie 在浏览器关闭时自动失效;持久化 Cookie 可以设置具体的过期时间,在过期时间之前,即使浏览器关闭,Cookie 仍然有效。
  • Session通常有一个固定的有效期,当会话过期后,服务器会自动销毁该会话及其相关的数据。会话的有效期可以根据应用的需求进行设置。

使用 cookie 时需要考虑的问题

  • Cookie:默认情况下,Cookie 是基于域名的,不同域名之间的 Cookie 是相互隔离的。如果需要实现跨域共享 Cookie,需要进行一些额外的配置,如设置domain属性。

  • 因为存储在客户端,容易被客户端篡改,使用前需要验证合法性,不要存储敏感数据(比如用户密码、账户余额)

  • 尽量减少 cookie 的体积,能存储的数据量不能超过 4kb

  • 一个浏览器针对一个网站最多存 20 个 Cookie,浏览器一般只允许存放 300 个 Cookie

  • 设置正确的 domain 和 path,减少数据传输

  • cookie 无法跨域

  • 移动端对 cookie 的支持不是很好,所以移动端常用的是 token

使用 session 时需要考虑的问题

  • 将 session 存储在服务器里面,当用户同时在线量比较多时,这些 session 会占据较多的内存,需要在服务端定期的去清理过期的 session

  • 当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 session 共享的问题。因为 session 是由单个服务器创建的,但是处理用户请求的服务器不一定是那个创建 session 的服务器,那么该服务器就无法拿到之前已经放入到 session 中的登录凭证之类的信息了。

  • 当多个应用要共享 session 时,除了以上问题,还会遇到跨域问题,因为不同的应用可能部署的主机不一样,需要在各个应用做好 cookie 跨域的处理。

  • sessionId 是存储在 cookie 中的,假如浏览器禁止 cookie 或不支持 cookie 怎么办?一般会把 sessionId 跟在 url 参数后面即重写 url,所以 session 不一定非得需要靠 cookie 实现

使用 token 时需要考虑的问题

  • 如果你认为用数据库来存储 token 会导致查询时间太长,可以选择放在内存当中。比如 redis 很适合你对 token 查询的需求
  • token 完全由应用管理,所以它可以避开同源策略
  • token 可以避免 CSRF 攻击 (因为不需要 cookie 了)
  • 移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token

cookie的存放位置,删除机制

存放位置

Cookie 是由服务器发给客户端的特殊信息,以文本文件方式存储在客户端,具体位置因操作系统和浏览器而异:

从存储介质角度,Cookie 有以下存储形式:

  • 文本文件:早期浏览器常将 Cookie 以文本文件存于硬盘特定文件夹,不同浏览器路径和命名规则有别。
  • 数据库:部分现代浏览器(如用 SQLite、IndexedDB 等)将 Cookie 存于数据库,更安全且便于管理查询
  • 内存:有些浏览器在内存存储 Cookie,仅在浏览器会话期间有效,关闭浏览器即清除,用于临时存会话或其他临时数据

删除机制

  • 自动删除

    • 会话级 Cookie:一旦浏览器关闭,这类 Cookie 就会自动清除 。
    • 过期删除:若 Cookie 设置了具体的过期时间 (Expires 属性 ) ,当到达该时间点,浏览器会自动将其删除。比如网站设置记住登录状态的 Cookie 有效期为一个月,一个月后该 Cookie 自动失效删除。在 Web 开发中,可通过设置 Cookie 的过期时间为 0 来实现删除。以 JavaScript 为例,document.cookie = "cookieName=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; ,这里将指定名称(cookieName)的 Cookie 过期时间设为过去时间,浏览器就会删除它 。在服务器端,如 PHP 中使用setcookie('cookieName', '', time() - 3600); (将过期时间设为一小时前)来删除 Cookie 。
  • 手动删除

    • 浏览器设置:几乎所有浏览器都提供手动删除 Cookie 的功能。

如何设置http缓存 ⭐️⭐️⭐️ 重点,热点

以下是设置 HTTP 缓存的详细步骤和策略,涵盖 强缓存协商缓存 的配置方法,适用于浏览器和 CDN 场景:


一、HTTP 缓存类型及核心头字段

缓存类型头字段作用
强缓存Cache-Control控制资源缓存的行为和有效期(优先级最高)
Expires指定资源过期时间(HTTP/1.0,优先级低)
协商缓存ETag / If-None-Match资源内容哈希值验证
Last-Modified / If-Modified-Since资源修改时间验证

二、强缓存配置(直接从本地缓存读取)

1. 设置 Cache-Control(推荐)
  • 语法示例
    Cache-Control: max-age=31536000, public, immutable
    
  • 常用指令
    • max-age=<seconds>:资源缓存时间(如 31536000 表示 1 年)。
    • public:允许所有缓存(浏览器、CDN、代理)缓存资源。
    • private仅允许浏览器缓存(禁止 CDN 和代理缓存)。
    • no-cache强制协商缓存(需向服务器验证)
    • no-store:禁止任何缓存(敏感数据场景)。
    • immutable声明资源永不变化(浏览器跳过验证)。
2. 设置 Expires(兼容旧浏览器)
  • 语法示例
    Expires: Wed, 21 Oct 2025 07:28:00 GMT
    
  • 注意:若同时设置 Cache-ControlExpires,以 Cache-Control 为准。
3. 适用场景
  • 静态资源(JS/CSS/图片):设置长期强缓存(如 1 年),通过文件名哈希(如 app.a1b2c3.js)实现内容更新。

三、协商缓存配置(向服务器验证缓存有效性)

1. 设置 ETag(基于内容哈希)
  • 服务端返回
    ETag: "a1b2c3d4e5"
    
  • 客户端请求
    If-None-Match: "a1b2c3d4e5"
    
  • 验证流程
    服务端比较客户端传来的 If-None-Match 与当前资源 ETag
    • 匹配 → 返回 304 Not Modified(空响应体)。
    • 不匹配 → 返回 200 OK 和新资源。
2. 设置 Last-Modified(基于修改时间)
  • 服务端返回
    Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
    
  • 客户端请求
    If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
    
  • 验证流程
    服务端比较客户端传来的 If-Modified-Since 与资源修改时间:
    • 未修改 → 返回 304 Not Modified
    • 已修改 → 返回 200 OK 和新资源。
3. 适用场景
  • 动态资源(HTML、API 响应):设置短时间缓存(如 max-age=0),依赖协商缓存验证更新。

四、缓存策略组合示例

1. 静态资源(强缓存 + 文件名 hash
Cache-Control: public, max-age=31536000, immutable
  • 文件名带哈希style.a1b2c3.css,内容变化时 URL 改变,自动跳过缓存。
  • 服务器配置示例(Nginx)
    location /static/ {
      add_header Cache-Control "public, max-age=31536000, immutable";
    }
    
2. 动态内容(协商缓存)
Cache-Control: no-cache
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
ETag: "a1b2c3d4e5"
  • 服务器配置示例(Express.js)
    app.get('/api/data', (req, res) => {
      const data = getData();
      res.set({
        'Cache-Control': 'no-cache',
        'Last-Modified': new Date().toUTCString(),
        'ETag': generateETag(data)
      });
      res.send(data);
    });
    
3. 禁止缓存(敏感数据)
  • 设置响应头:
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Expires: 0

五、调试与验证

  1. 浏览器开发者工具

    • Network 面板:查看请求的 Status Code(200/304)和响应头。
    • 响应状态码200 (from disk cache) 或 200 (from memory cache)disk cache 表示强缓存,(from memory cache) 表示内存缓存。
  2. 命令行工具

    curl -I http://example.com/resource.js
    # 查看返回的 Cache-Control、ETag 等头字段
    

disk cache(磁盘缓存)和 from memory cache(内存缓存)都是浏览器缓存静态资源(如图片、JS、CSS)的方式,核心区别是缓存位置不同,导致读取速度、持久性和适用场景完全不一样。

核心区别对比
对比维度from memory cache(内存缓存)disk cache(磁盘缓存)
存储位置浏览器内存电脑硬盘 / SSD
读取速度极快(微秒级)较慢(毫秒级)
持久性临时,关闭标签 / 浏览器后消失持久,重启后仍存在
资源体积偏好体积小的资源体积较大的资源

简单总结:内存缓存是 “临时快取”,为当前会话提速;磁盘缓存是 “长期仓库”,为下次访问省钱省时间。浏览器会自动根据资源特性,优先用内存缓存,再用磁盘缓存,最后才从服务器下载

缓存优先级

浏览器优先读取顺序:

Service Worker 缓存 > Memory Cache > Disk Cache > Web Storage 缓存 > 请求服务器 

六、常见问题与解决方案

问题解决方案
资源更新后用户看到旧版本修改文件名(添加哈希)或增加查询参数(如 ?v=2
缓存时间过长导致无法及时更新动态资源设置 max-age=0no-cache,依赖协商缓存
CDN 不遵循缓存头检查 CDN 配置,确保不覆盖 Cache-Control,或设置 CDN 缓存规则与服务器一致
缓存敏感数据(如用户信息)设置 Cache-Control: private, no-store

七、面试常见问题示例

面试问题涉及考点
浏览器强缓存和协商缓存的区别?状态码、是否请求服务器
Cache-Control 常见取值有哪些?no-cacheno-storemax-age
ETag 与 Last-Modified 有什么区别?精度、性能、误判可能性
HTML 页面应该如何设置缓存策略?通常设置为 no-cache
浏览器缓存有哪些层级?memory、disk、Service Worker
如何设计静态资源缓存方案?文件名加 hash,配置强缓存头

常见考点

  1. 缓存的基本概念
  2. 强缓存 vs. 协商缓存
  3. 强缓存Cache-ControlExpires
  4. 协商缓存ETagLast-Modified
  5. 缓存优先级:强缓存 > 协商缓存 > 无缓存
  6. 缓存的生命周期
  7. 缓存控制指令max-ages-maxageno-cacheno-storemust-revalidate
  8. Cache-Control的常见值及作用
  9. 浏览器缓存的类型:内存缓存、磁盘缓存
  10. HTTP请求中的缓存相关头部If-None-MatchIf-Modified-Since
  11. Service Worker缓存
  12. 缓存的影响因素:请求头、响应头、用户设置等
  13. 跨域资源缓存问题:CORS和缓存
  14. 缓存清除机制
  15. 缓存穿透与缓存雪崩问题
  16. CDN与缓存
  17. 版本控制和缓存更新策略
HTML 通常不使用强缓存
  • 避免首页更新被缓存 → 设置为 no-cache 或短时间缓存
 <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">

总结

  • 强缓存:适合内容不变的静态资源,通过 Cache-Control: max-age + 文件名哈希实现长期缓存。
  • 协商缓存:适合动态内容,通过 ETagLast-Modified 验证资源是否更新。
  • 组合策略静态资源强缓存 + 动态内容协商缓存,结合 CDN 加速
  • 调试工具:浏览器开发者工具和命令行工具验证缓存行为。

浏览器的存储机制

浏览器的存储机制涵盖多种技术,目的是满足 Web 应用在不同场景下的数据持久化、缓存和离线访问需求。它们各自具有不同的存储容量、生命周期、安全策略和访问方式,理解这些机制对于构建高效、安全的前端应用至关重要。


一、浏览器存储机制分类

1. Cookie

最早期的存储机制,主要用于会话管理和身份认证。

  • 容量限制:单个约 4KB,总数有限制;
  • 生命周期:可设置过期时间或为会话级;
  • 访问方式:由浏览器自动在 HTTP 请求头中携带,也能通过 JS 访问(除非设置 HttpOnly);
  • 安全性:可设置 HttpOnly、Secure、SameSite 防范安全风险。
2. Web Storage(LocalStorage 和 SessionStorage)

HTML5 新增的简单键值对存储方案。

  • LocalStorage:永久存储,关闭浏览器数据仍保留,同源可访问;
  • SessionStorage:页面会话存储,关闭标签页即清空;
  • 容量:一般为 5~10MB;
  • 访问方式同步 API,容易使用但可能阻塞主线程
3. IndexedDB

浏览器内置的底层结构化数据库支持事务和索引,适合复杂和大容量数据存储。

  • 容量:远大于 LocalStorage,通常以设备剩余空间为限;
  • 访问方式异步 API,支持复杂操作;
  • 用途:离线应用、大数据缓存、文件存储等。
4. Cache Storage

由 Service Worker 管理的请求和响应缓存,用于离线和加速访问。

  • 容量:较大,依赖设备和浏览器策略;
  • 访问方式:异步 Promise API;
  • 用途:缓存静态资源、接口响应,实现离线支持。
5. Service Worker

虽然不是存储机制本身,但作为浏览器后台代理进程,管理 Cache Storage,实现网络请求拦截和缓存策略,是现代离线应用的核心。

  • 生命周期独立于页面,可在后台运行;
  • 控制页面的网络请求,提供离线能力和资源预缓存;
  • 可结合 Cache Storage 和 IndexedDB 进行数据管理

二、存储机制的生命周期与访问作用域

  • Cookie:基于域和路径,可设置 HttpOnly、Secure 限制访问;
  • LocalStorage/SessionStorage:基于同源策略,SessionStorage 进一步限定于标签页会话;
  • IndexedDB 和 Cache Storage:基于同源,支持版本控制和升级;
  • Service Worker:独立于页面,能控制同源下的所有相关页面。

三、容量限制与性能影响

  • Cookie 容量最小,且会随每次请求自动发送,影响网络性能;
  • LocalStorage/SessionStorage 适合轻量存储,容量适中;
  • IndexedDB 和 Cache Storage 容量大,适合海量数据和文件缓存;
  • Service Worker 通过异步调度,避免阻塞主线程。

四、安全与隐私考虑

  • Cookie 可被服务器访问,设置 HttpOnly 避免脚本窃取;
  • Web Storage、IndexedDB 只能由同源脚本访问,防止跨站数据泄漏;
  • Service Worker 需 HTTPS 环境,避免被恶意注入;
  • 用户隐私模式下,存储行为可能受限,数据不保证持久。

五、应用场景及选择建议

  • 需要与服务器频繁交互、会话维持时用 Cookie;
  • 存储简单配置、少量数据用 LocalStorage;
  • 页面会话临时数据用 SessionStorage;
  • 大规模结构化数据和离线存储用 IndexedDB;
  • 静态资源及请求缓存用 Cache Storage,配合 Service Worker 提升离线体验和性能;
  • Service Worker 负责管理缓存和拦截网络请求,实现 PWA 功能。

常见考点

面试考察点通常围绕存储类型、特点、使用场景、容量限制、安全性和生命周期展开:

  1. 浏览器有哪些本地存储方式?分别有什么特点?
  2. Cookie 和 LocalStorage 的区别是什么?
  3. 如何安全使用 Cookie?HttpOnly 和 Secure 有什么作用?
  4. SessionStorage 和 LocalStorage 有哪些区别?
  5. IndexedDB 的优势和适用场景?
  6. 如何使用 Cache Storage 实现离线缓存?
  7. 存储容量限制和浏览器兼容性问题?
  8. 如何避免本地存储的数据被篡改或泄露?
  9. 存储的生命周期和访问范围如何理解?
  10. 同源策略对浏览器存储的影响?

关联面试题

存储容量限制 & 浏览器兼容性

存储类型容量限制兼容性
Cookie4KB / 个,最多 20 个 / 域名所有浏览器兼容
localStorage/sessionStorage5MB / 域名IE8+、主流浏览器均支持
IndexedDB一般 250MB~ 无上限(视浏览器 / 设备)IE10+、主流浏览器支持
Service Worker Cache同 IndexedDBChrome/Firefox/Edge 支持,Safari 11.1+ 支持

总结:Cookie 容量最小,localStorage 够用且兼容性好,大容量数据用 IndexedDB。

避免本地存储数据篡改 / 泄露

  1. 敏感数据不存前端:密码、token 等核心数据绝不直接存,可存加密后的摘要(如 AES 加密)。
  2. 数据签名校验:存数据时附带后端生成的签名(如 HMAC),读取时校验签名,篡改则失效。
  3. 合理设置存储属性:Cookie 加 HttpOnly(防 JS 读取)、Secure(仅 HTTPS 传输)、SameSite=Strict(防 CSRF)。
  4. 定期清理 + 加密存储:敏感数据用完即删,localStorage 存数据时用加密算法(如 CryptoJS)处理。

存储生命周期 & 访问范围

存储类型生命周期访问范围
Cookie可设置 expires/max-age(持久),或会话级(关闭浏览器失效)同源 + 指定域名 / 路径,请求自动携带
localStorage持久化,除非手动删除 / 清理缓存同源域名内所有页面共享
sessionStorage会话级,关闭标签页 / 浏览器即失效仅当前标签页有效,同源其他标签页不可访问
IndexedDB持久化,手动删除才消失同源域名内共享

同源策略对浏览器存储的影响

同源策略(协议 + 域名 + 端口一致)是浏览器安全核心,限制不同源页面访问彼此存储数据

  1. 同源页面:可共享 localStorage/sessionStorage/Cookie/IndexedDB。
  2. 不同源页面:完全隔离,无法读取对方存储的数据。
  3. 特例:Cookie 可通过设置 domain 实现主域下子域名共享(如 a.example.comb.example.com 共享)。

cookie 的有效时间设置为 0 会怎么样

Cookie过期时间设置为0,表示跟随系统默认,其销毁与Session销毁时间相同,会在浏览器关闭后删除。

使用cookie、session维持登录状态的原理是什么?

什么是 Samesite Cookie 属性?

SameSite 是HTTP响应头 Set-Cookie 的属性之一。它允许声明该 Cookie 是否仅限于第一方或者同一站点上下文。

  • 将 Samesite 设为 strict ,这种称为严格模式,表示这个 cookie 在任何情况下都不可能作为第三方 cookie。
  • 将 Samesite 设为 Lax ,这种模式称为宽松模式,也是目前浏览器中的默认值。如果这个请求是个 GET 请求,并且这个请求改变了当前页面或者打开了新的页面,那么这个 cookie 可以作为第三方 cookie,其余情况下都不能作为第三方 cookie。使用这种方法的缺点是,因为它不支持子域,所以子域没有办法与主域共享登录信息,每次转入子域的网站,都需要重新登录。还有一个问题就是它的兼容性不够好。
  • 将 Samesite 设为 None,Cookie将在所有上下文中发送,即允许跨域发送。

响应头设置方式:

Set-Cookie: flavor=choco; SameSite=None; Secure

Service Worker 是如何缓存 http 请求资源的?

Service Worker 通过拦截 HTTP 请求,并使用缓存 API 存储和管理缓存资源,使得应用能够离线访问,提高了应用的性能和可靠性。核心过程包括注册 Service Worker、在 install 事件中预缓存资源、在 fetch 事件中拦截请求并从缓存或网络返回资源,以及在 activate 事件中进行缓存清理。

Cookie 的 SameSite 属性有什么作用? 防止 CSRF 攻击和用户追踪

跨域时怎么处理 cookie?

WebWorker、SharedWorker 和 ServiceWorker 有哪些区别?

Service worker是什么?

service worker是PWA的重要组成部分,W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存,也是Web Worker的升级版

Service worker (简称 SW) 是一个注册在指定源和路径下的事件驱动 Worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是网络不可用)下的表现。

CDN的作用和原理 ⭐️ 重点

CDN 通过 边缘节点缓存 + 智能路由分发 实现了内容的高效传递,成为现代 Web 服务的核心基础设施。

安装推送的类型

1)主动推送:由源站服务器,负责分发内容至CDN边缘节点,然后智能DNS引导用户去就近CDN节点。
2)被动推送:用户通过智能DNS,访问到就近CDN节点,然后索引文件,本地没发现该文件,然后本地就从源站请求数据,然后缓存到本地,再推送给用户。

CDN(内容分发网络) 是一种通过 分布式边缘节点缓存内容 的技术,旨在加速用户访问速度、降低源站负载并提升服务稳定性。以下是其核心作用与工作原理的详细解析:


一、CDN 的核心作用

1、提高用户访问的速度。
2、减轻源站服务器的压力。
3、提高并发能力(分布式架构)。


内容分发网络(CDN)是一种通过分布式服务器节点内容传输的技术,旨在提升用户访问网站或应用的速度与稳定性。以下是对CDN的详细解析:


1. CDN的核心原理

  • 地理分布:CDN在全球多个位置部署边缘节点,缓存源站的静态资源(如图片、视频、CSS/JS文件)。
  • 就近访问:用户请求被路由到最近的节点,减少物理距离带来的延迟
  • 缓存机制节点存储内容,减少直接回源站的请求,降低源站负载。

2. CDN的关键组成部分

  • 边缘节点(Edge Server)直接与用户交互的服务器,负责内容缓存和快速响应。
  • 中心节点(Origin Shield):部分CDN设置中心层,进一步减少源站压力。
  • 负载均衡系统:通过DNS或Anycast技术分配用户请求到最优节点
  • 回源机制边缘节点未缓存或缓存过期时,向源站请求资源并存储。

image.png


3. CDN的工作流程

  1. 用户发起请求:输入网址。
  2. DNS解析:CDN的智能DNS根据用户位置返回最佳节点IP
  3. 节点响应
    • 若资源已缓存且未过期,直接返回给用户。
    • 若资源过期或未缓存,节点从源站拉取并更新缓存。

4. CDN的主要应用场景

  • 静态资源加速:网页、图片、文档等内容的全球分发。
  • 大文件下载:游戏更新、软件安装包的分发。

5. CDN的优势

  • 提升速度:用户请求被路由到最近的节点,减少物理距离带来的延迟,改善用户体验(如页面加载时间缩短30%-50%)。
  • 减轻源站服务器的压力:源站流量减少。
  • 提高并发能力(分布式架构)
  • 提升可用性和抗 DDoS 攻击能力

6. 挑战与注意事项

  • 动态内容限制:传统CDN对动态内容(如实时数据)加速效果有限,需结合其他技术。
  • 成本管理:按流量或请求计费可能增加费用,需根据业务需求选择套餐。
  • 隐私合规:全球节点可能涉及数据跨境存储,需符合GDPR等法规。

7. 主流CDN服务商

  • 企业级:Akamai(全球最大)、Cloudflare(以安全著称)、AWS CloudFront(深度集成云服务)。
  • 国内服务:阿里云CDN、腾讯云CDN、网宿科技。
  • 开源方案:Traefik、Caddy(轻量级反向代理/CDN功能)。

8. 实际案例

  • 电商大促:天猫“双11”通过CDN处理PB级流量,避免服务器崩溃。
  • 视频平台:抖音使用CDN实现低延迟直播,支持千万级并发。
  • 全球化企业:Spotify利用CDN快速分发音乐文件至不同地区用户。

9. 负载均衡系统

由于没有返回 IP 地址,于是本地 DNS 会向负载均衡系统再发送请求 ,则进入到 CDN 的全局负载均衡系统进行智能调度

  • 看用户的 IP 地址,查表得知地理位置,找相对最近的边缘节点

  • 看用户所在的运营商网络,找相同网络的边缘节点

  • 检查边缘节点的负载情况,找负载较轻的节点

  • 其他,比如节点的 “健康状况”、服务能力、带宽、响应时间等

结合上面的因素,得到最合适的边缘节点,然后把这个节点返回给用户,用户就能够就近访问 CDN 的缓存代理


CDN已成为现代互联网基础设施的核心组件,尤其在数字化转型和全球化业务扩展中不可或缺。通过CDN的负载均衡系统,智能调度边缘节点提供服务,不仅能提升用户体验,还能增强业务的稳定性和安全性。

CDN 节点缓存是如何更新的

CDN 节点缓存更新核心是触发缓存失效,主要有 3 类机制:

  1. 过期自动更新依据资源响应头的缓存策略(如 Cache-Controlmax-age),缓存到期后,CDN 节点会主动回源站拉取最新资源,更新本地缓存。

  2. 主动刷新(主动 Purge)

    • 开发者通过 CDN 控制台或 API,提交需要刷新的资源 URL / 目录,强制 CDN 节点删除对应缓存。
    • 适用场景:发布紧急版本、修复线上 bug 时,立即让用户获取最新资源
    • 注意:频繁全量刷新会增加源站压力,建议精准刷新(指定 URL)。
  3. 被动刷新(缓存穿透触发) 当用户请求的资源在 CDN 节点已过期 / 不存在时,节点会回源拉取最新资源并缓存,同时返回给用户。

如何避免缓存过期 & 强制刷新方法

  1. 避免过期:资源加内容哈希命名(如app.5f8a.js),配合max-age=31536000(缓存 1 年),内容变则 URL 变

  2. 强制刷新

    • 客户端:Ctrl+F5 或 清缓存
    • 开发 / 测试:URL 加版本号(app.js?v=2
    • 生产环境:CDN 主动刷新 或 设Cache-Control: no-cache(强制协商缓存)

如何区分“热资源”和“冷资源”的缓存策略?

热资源:访问频率高、时效性强、带宽消耗大(如首页 JS/CSS、热门图片、活动页)冷资源:访问频率低、更新少、存储占比高(如历史文档、归档图片、低频接口数据)

维度热资源缓存策略冷资源缓存策略
缓存有效期适中(如 1~24 小时),避免过期后大量回源长期(如 30 天~1 年),降低回源次数
CDN 节点部署优先部署在边缘节点(靠近用户),提升命中率部署在中心节点,节省边缘节点存储空间
刷新策略支持主动刷新,保证时效性仅被动刷新(过期后回源),减少运维成本
缓存粒度细粒度(按文件 / URL 缓存),精准控制更新粗粒度(按目录缓存),降低管理复杂度
优先级高优先级缓存,分配更多带宽 / 内存低优先级缓存,可被热资源挤出(LRU 淘汰机制)
典型配置Cache-Control: public, max-age=3600 + ETagCache-Control: public, max-age=2592000 + 不设置协商缓存

Vue2 项目实践

  • 热资源(app.xxx.jsvendor.xxx.js):webpack 构建时加哈希,CDN 边缘节点缓存,设置 1 天有效期
  • 冷资源(static/archives/xxx.pdf):上传至 CDN 低频存储节点,设置 30 天有效期,不配置主动刷新

CDN面试常见问题

  1. CDN 的原理是什么?它解决了哪些问题?

  2. 浏览器请求 CDN 资源时如何定位到最近的节点?

  3. CDN 缓存失效策略有哪些?如何手动刷新?

  4. 如何让资源文件在更新后立即生效?文件哈希、CND主动刷新、禁用缓存

  5. 使用 CDN 的时候,如何配置静态资源的缓存策略

    推荐组合:Cache-Control: public, max-age=86400 + ETag

    • public:允许 CDN / 代理缓存
    • max-age=86400:缓存 1 天
    • ETag:资源更新时触发协商缓存,返回 304 减少带宽
  6. CDN 是否可以缓存动态接口?如果要缓存,有哪些方式

    CDN 可以缓存动态接口,核心是 标准化动态内容的缓存条件,适用场景:非实时数据(如商品列表、文章详情)。

  7. CDN 如何支持 HTTPS? CDN 支持 HTTPS 核心是证书部署 + 协议转换,步骤如下:

    1. 配置 SSL 证书:在 CDN 控制台上传自有证书,或直接使用厂商提供的免费证书(自动续签)。
    2. 边缘节点握手:用户与 CDN 边缘节点建立 HTTPS 连接,完成加密传输。
    3. 回源协议可选:CDN 与源站之间可选择 HTTPS(安全)或 HTTP(内网环境高效)通信。
    4. 可选强制跳转:配置 HTTP 请求 301 重定向到 HTTPS,避免混合内容风险。
  8. CDN 缓存命中率下降的可能原因有哪些?

    • 资源粒度问题:资源 URL 碎片化(如带随机参数),导致缓存键过多,无法复用

    • 缓存时间过短max-age 设置太小,缓存频繁过期,大量请求回源

    • 冷门资源占比高:冷资源访问频率低,缓存易被 LRU 算法淘汰

    • 缓存配置错误:源站返回 Cache-Control: private(禁止 CDN 缓存)或 no-cache

    • 用户地域分散:部分边缘节点资源未预热,首次请求均回源

  9. CDN 如何处理多个用户同时请求一个不存在的资源?

    1. 首个用户请求不存在的资源 → CDN 回源查询 → 源站返回 404
    2. CDN 缓存这个 404 响应(默认短时效,如 1~5 分钟)
    3. 同时间段内其他用户请求该资源 → 直接返回缓存的 404,不再回源
  10. 为什么推荐将静态资源放到cdn上? 推荐静态资源放 CDN 核心是 提速、降本、稳服务,简单说三点:

    1. 就近访问,加载更快:CDN 边缘节点分布广,用户从最近节点取资源,不用跨地域连源站,大幅降低延迟(比如图片、JS 加载时间减半)。
    2. 分流减压,降低成本:源站不用处理海量静态资源请求,带宽压力骤减;同时 CDN 按使用量计费,比自建高带宽服务器更划算。
    3. 提升稳定性,抗峰值:CDN 有负载均衡和容灾能力,秒杀、大促等高并发场景下,能避免源站宕机,保证资源正常访问。

谈谈你对TCP三次握手和四次挥手的理解

三次握手(连接建立)

  1. 第一次握手(SYN)

    • 客户端发送带有SYN(同步序列号)标志的数据包,并选择初始序列号(ISN),进入SYN_SENT状态。
    • 目的:告知服务器客户端希望建立连接,并同步初始序列号。
  2. 第二次握手(SYN-ACK)

    • 服务器收到SYN后,发送带有SYN和ACK(确认)标志的数据包,确认客户端的序列号(ISN+1),并发送自己的ISN,进入SYN_RECEIVED状态。
    • 目的:确认客户端的请求,并同步服务器的初始序列号。
  3. 第三次握手(ACK)

    • 客户端收到SYN-ACK后,发送ACK标志的数据包,确认服务器的序列号(ISN+1),双方进入ESTABLISHED状态。
    • 目的:确认服务器的响应,完成双向通信准备。

image.png

为什么需要三次握手,两次不行吗?

确保双向通信能力:三次交互验证了双方的发送和接收能力

  • 第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
  • 第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
  • 第三次握手:客户端发包,服务端收到了。

这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

四次挥手(连接断开)

  1. 第一次挥手(FIN)

    • 如客户端 发送FIN标志的数据包,进入FIN_WAIT_1状态。
    • 含义不再发送数据,但可接收数据
  2. 第二次挥手(ACK)

    • 如服务器 收到FIN后,发送ACK确认,进入CLOSE_WAIT状态。
    • 如客户端 收到ACK后进入FIN_WAIT_2状态。
    • 含义确认收到关闭请求,允许服务器处理剩余数据
  3. 第三次挥手(FIN)

    • 如服务器 处理完数据后,发送FIN标志的数据包,进入LAST_ACK状态。
    • 含义:通知如客户端已准备好关闭连接。
  4. 第四次挥手(ACK)

    • 如客户端 收到FIN后,发送ACK确认,进入TIME_WAIT状态(等待2MSL时间后关闭)。
    • 如服务器 收到ACK后立即关闭连接。
    • 含义:确保被动方收到确认,防止报文丢失导致的重传。

image.png

image.png

为何需要四次?

因为当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的SYN 报文是用来同步的。但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉客户端,"你发的 FIN 报文我收到了"。只有等到服务端所有的报文都发送完了,才能发送 FIN 报文,因此不能一起发送。故需要四次挥手

总结

  • 三次握手确保双方具备收发能力,同步序列号,防止历史连接问题。
  • 四次挥手:优雅关闭双向通道,处理剩余数据,保证可靠性
  • 优化实践:减少频繁连接(复用连接,如HTTP Keep-Alive)。

TCP 有哪些手段保证可靠交付 / TCP 为什么是可靠的 ⭐️ 重点

1.确认应答(ACK)机制

  • 原理:发送方将数据分割成报文段发送给接收方,接收方收到报文段后,会向发送方发送一个确认(ACK)报文其中包含确认号该确认号表示接收方已成功接收该序号之前的所有数据。例如,接收方收到序号为 1 - 100 的字节数据,会返回确认号为 101 的 ACK 报文,告知发送方 1 - 100 字节已成功接收。
  • 作用:发送方通过接收 ACK 报文,能知晓哪些数据已被成功接收,哪些可能丢失需要重传,以此确保数据不丢失

2.超时重传机制

  • 原理发送方每发送一个报文段,就启动一个定时器。若在定时器设置的重传时间(RTO,Retransmission Time - Out )内未收到对应的 ACK 报文,就认为该报文段可能在传输中丢失或 ACK 报文丢失,进而重传该报文段 。RTO 的设置至关重要,它会根据连接往返时间(RTT,Round Trip Time )动态调整。例如,在网络状况较好时,RTT 较短,RTO 也会相应缩短,使重传更及时;网络拥堵时,RTT 变长,RTO 也增大,避免不必要的重传加剧网络拥塞。
  • 作用:在数据传输出现 丢包 等异常时,通过重传确保数据最终能可靠到达接收方。

3.序列号与确认号机制

  • 原理:TCP 给每个要发送的字节数据都分配一个序列号,发送方按顺序发送报文段。接收方根据序列号对收到的数据进行排序,重组出正确顺序的字节流确认号则是接收方告知发送方下一个期望接收的字节序号。例如,发送方发送的第一个报文段包含序列号为 1 - 100 的字节,接收方若正确接收,返回的确认号为 101;若只收到序列号 1 - 50 的字节,会缓存这些数据,等待后续 51 - 100 字节到达后再一起确认,或者先返回确认号为 51 的报文,要求发送方重传 51 - 100 字节。
  • 作用:保证数据按序到达接收方,防止数据乱序或重复,确保接收方最终能按正确顺序将数据交付给应用层。

4.校验和机制

  • 原理:发送方在发送报文段前,对报文段首部和数据部分的所有 16 位字(以二进制形式)相加,然后将结果取反,得到校验和,并将其放置在 TCP 首部。接收方收到报文段后,同样对报文段进行校验和计算,再与接收到的校验和进行比较
  • 作用:检测数据在传输过程中是否因网络干扰等原因发生变化(如比特翻转)。若校验和不匹配,接收方会丢弃该报文段,不发送 ACK 确认,促使发送方超时重传,保证接收数据的正确性

5.流量控制机制

  • 原理:利用滑动窗口协议实现。接收方在返回的 ACK 报文中,通过窗口字段告知发送方自己 接收窗口大小。发送方依据接收方通告的窗口大小,动态调整自己的发送速率,发送窗口大小不会超过接收窗口。例如,接收方通告窗口大小为 1000 字节,发送方在未收到新的窗口调整通知前,最多只能发送 1000 字节的数据。
  • 作用:防止发送方发送数据过快,导致接收方缓冲区溢出而丢包,确保接收方有足够能力处理接收的数据,保证发送和接收速度

6.拥塞控制机制

原理:TCP 拥塞控制有慢启动、拥塞避免、快速重传、快速恢复等算法。

  • 慢启动时,发送方初始拥塞窗口cwnd,Congestion Window)较小,一般为一个最大报文段长度MSS,Maximum Segment Size),每收到一个 ACK 确认,cwnd 增加一个 MSS,使发送速率逐渐提升;
  • 达到慢启动门限(ssthresh)后进入拥塞避免阶段,此后每收到一个 ACK,cwnd 增加 1/cwnd 个 MSS,避免网络拥塞快速加剧;
  • 当发送方收到三个重复的 ACK 时,进入快速重传,立刻重传丢失的报文段,而不是等待超时
  • 快速重传后进入快速恢复阶段,调整 cwnd 和 ssthresh 等参数,继续控制发送速率。

作用:根据网络的拥塞状况动态调整发送方的发送速率,避免网络出现拥塞,保证网络整体的可靠传输。

UDP 为什么更快?

  • 无需建立连接(无三次握手)
  • 没有确认和重传机制那些机制

TCP如何做拥塞控制

1.慢启动
2.拥塞控制
3.快重传
4.快恢复

什么是TCP粘包

TCP 粘包是指在基于 TCP 协议进行网络通信时,接收方收到的数据包并非按照发送方的发送顺序和边界准确区分,多个数据包内容粘连在一起的现象 。比如发送方先后发送 “Hello” 和 “World” 两个数据包,接收方可能一次性收到 “HelloWorld” ,难以准确解析原始消息内容。

TCP 产生粘包的原因主要有:

  • 发送端合并机制:发送端为提高传输效率,会采用策略合并小数据包典型的 Nagle 算法,当发送方有未确认小数据包在网络传输时,新小数据包会被缓存,等确认后将缓存与新数据包合并发送。如传感器频繁发小数据,经 Nagle 算法可能合并成一个数据包发给服务器,引发粘包。
  • 接收端读取延迟:接收端应用程序处理数据速度慢,TCP 接收缓冲区不断有新数据到达,若未及时读取,后续数据会与未读数据粘连,使接收端无法准确区分数据包边界。像文件传输中,客户端处理能力有限,不能及时处理接收数据,缓冲区数据积累,读取时可能就会出现粘包。
  • 网络传输限制:IP 层分片重组可能导致数据合并。当应用层数据超最大传输单元(MTU),TCP 会分片传输,接收端需正确组装分片。若分片顺序错或丢失,可能导致粘包。另外,TCP 建立连接时双方协商的最大报文段长度(MSS)也有影响,数据超 MSS 会被拆分,接收端组装报文段出错也可能引发粘包 。

如何处理粘包现象?

应用层处理
  • 固定格式法:给传输的数据加上固定格式,比如以特定字符作为开始符和结束符 。像发送数据 “Hello” 时,可在前后添加特殊字符,变为 “#Hello$” 。接收方在接收到数据后,依据特殊字符来判断数据包边界,解析出原始数据。不过要留意,数据内容里不能出现与特殊字符相同的字符,否则会干扰解析。
  • 长度标识法:发送数据前,先告知接收方数据长度。常见做法是在数据头部设置固定字节数(如 4 字节)来表示后续真实数据的长度 。例如发送一段文本数据,先将文本长度用 4 字节表示并发送,接收方先读取这 4 字节,得知后续文本数据长度,再按此长度读取真实数据。
  • 协议报头法:构建自定义协议报头,报头包含数据长度、数据类型等信息。发送时,先序列化报头(如用 JSON 等格式),再将报头长度、报头内容、真实数据依次发送。接收方先读报头长度,再根据长度读报头内容,解析报头获取数据信息后,按信息读真实数据。
发送方处理
  • 关闭 Nagle 算法:Nagle 算法可能引发发送方粘包。在某些场景下,可通过设置 TCP_NODELAY 选项关闭该算法,强制数据立即发送,避免小数据包合并,但这样会降低网络发送效率。
  • 使用 push 操作指令:TCP 提供的 push 操作指令可让发送方不等待缓冲区满,直接发送本段数据,减少因缓冲区积攒数据导致的粘包,但也会一定程度影响传输效率优化。
接收方处理
  • 优化程序设计:精简接收进程工作量,比如减少不必要的计算、磁盘 I/O 等操作,让接收进程能及时处理接收缓冲区的数据,降低粘包概率。
  • 提高接收进程优先级:在操作系统层面提高接收进程优先级,使其能优先获取系统资源,及时从缓冲区读取数据,防止因处理不及时造成粘包 。
  • 分包接收合并:接收方按数据结构字段,分多次接收一包数据再合并。比如接收包含多个字段的数据包,可按字段顺序依次接收并组装,但此方法会降低应用程序效率,不太适用于实时性要求高的场景。

TCP 与 UDP 的区别是什么,既然 TCP 是可靠的,那它有啥缺点 ⭐️⭐️ 重点

TCP(传输控制协议)与 UDP(用户数据报 协议)有以下区别:

  • 连接方式

    • TCP 是面向连接的协议,在数据传输之前,发送方和接收方需要先建立连接,就像打电话一样,需要先拨号接通,然后才能进行通话。
    • UDP 是无连接的协议,发送方无需与接收方建立连接就可以直接发送数据,类似于写信,不需要事先通知对方就可以把信寄出去。
  • 可靠性

    • TCP 提供可靠的传输服务,通过序列号、确认应答、重传机制等保证数据的准确传输,能确保数据无差错、不丢失、不重复且按序到达。
    • UDP 不保证数据的可靠传输,数据可能会丢失、重复或乱序到达,就像信件在邮寄过程中可能会丢失或延迟,但它也因此具有简单、高效的特点。
  • 数据传输效率

    • TCP 在传输数据时,需要进行连接建立、维护和断开等操作,并且有各种控制机制,所以传输效率相对较低
    • UDP 没有这些额外的操作和控制机制,数据传输效率较高,适合对实时性要求高、允许一定数据丢失的场景,如视频直播、实时游戏等。
  • 数据格式

    • TCP 是流式协议,数据像水流一样连续传输,没有明确的边界,需要应用层自己处理数据的边界问题,可能会出现粘包现象
    • UDP 是面向报文的协议,每个 UDP 数据包都有明确的边界,发送方发送的是一个个独立的报文,接收方也是以报文为单位进行接收。

虽然 TCP 是可靠的,但它也存在一些缺点:

  • 传输效率相对较低:由于 TCP 为保证数据可靠性,有复杂的确认、重传等机制,在数据传输过程中会增加额外的开销,导致传输效率不如 UDP 高。特别是在一些网络环境较好、对数据准确性要求不是极高的场景下,这些额外开销可能会显得多余。
  • 连接建立和维护开销大:TCP 连接的建立需要经过三次握手,连接的拆除需要经过四次挥手,这都需要消耗一定的时间和资源。在短连接的应用场景中,频繁地建立和拆除连接会带来较大的开销,影响系统性能。
  • 对系统资源要求较高:TCP 需要在发送方和接收方维护连接状态信息,包括发送和接收缓冲区、序列号、确认号等,这需要占用一定的内存空间。当同时处理大量连接时,对系统的内存等资源要求较高,可能会成为系统性能的瓶颈。
  • 实时性较差:因为 TCP 要保证数据的可靠传输和顺序性,当出现丢包或网络拥塞时,会进行重传和流量控制,这可能导致数据传输的延迟增加,不太适合对实时性要求极高的应用如实时音视频通话,如果出现延迟会严重影响用户体验。

TCP与UDP的详细区别

头部开销
  • TCP头部较大(至少20字节)

    • 包含序列号、确认号、窗口大小、校验和等字段。
  • UDP头部极小(仅8字节)

    • 仅包含源端口、目的端口、长度和校验和。

典型协议
  • TCP协议族
    • HTTP/HTTPS、FTP、SMTP、SSH、Telnet。
  • UDP协议族
    • DNSQUIC(HTTP/3底层协议)、RTP(实时传输协议)。

扩展对比表

特性TCPUDP
连接方式面向连接(三次握手)无连接
应用场景网页浏览(HTTP/HTTPS)实时音视频(Zoom、直播)
可靠性可靠(确认、重传、拥塞控制)不可靠(可能丢包、乱序)
传输模式字节流数据报
传输效率较低(高开销)极高(低开销)
数据顺序严格保证顺序不保证顺序
头部大小20~60字节8字节
适用场景数据完整性优先实时性优先

如何选择协议?

  • 选择TCP的情况

    • 需确保数据完整到达(如文件下载网页加载)。
    • 需按顺序处理数据(如数据库事务)。
  • 选择UDP的情况

    • 实时性要求高于可靠性(如视频会议语音通话)。
    • 高频次小数据包传输(如传感器上报)。

高级应用:结合TCP与UDP的优势

  • QUIC协议(HTTP/3的基础):
    • 基于UDP实现,但内置了类似TCP的可靠性机制(如丢包重传拥塞控制)。
    • 减少握手延迟(0-RTT连接建立),适合移动网络和高延迟环境。

总结

  • TCP 是“可靠的信使”,适合对数据完整性要求高的场景
  • UDP 是“高效的快递员”,适合实时性和效率优先的应用。
  • 实际开发中需根据业务需求权衡两者的特性,必要时可结合使用(如QUIC协议)。

TCP 的性能与机制考察

1. 为什么 TCP 有队头阻塞?

  • TCP 是流式协议,数据必须按顺序到达,前面包未收到 → 后面包无法处理

2. 如何减少 TCP 连接建立开销?

  • 使用 keep-alive
  • 启用 HTTP/2 多路复用
  • 升级为 HTTP/3(使用 QUIC)

3. TCP 慢启动机制?

  • 为防止拥塞,连接初期传输速率缓慢逐步升高

UDP 的典型应用考察

  • 直播场景:使用 UDP 提高实时性,轻微丢包不影响观看
  • 游戏通信:低延迟优先,逻辑冗余可容忍数据丢失
  • DNS 查询:一次性请求,快速返回
  • QUIC 协议:基于 UDP 实现的可靠传输,解决 TCP 队头阻塞问题

面试常见问题示例

问题涉及知识点
TCP 和 UDP 的区别?连接性、可靠性、效率、应用场景
TCP 是如何保证数据可靠的?序列号、确认应答、超时重传、窗口机制
TCP 为什么慢?建连握手、拥塞控制、重传机制
UDP 丢包了怎么办?不处理,应用层自行容错或忽略
HTTP/3 为什么用 UDP?避免 TCP 队头阻塞、提升连接建立速度
WebSocket 基于 TCP 吗?是的,长连接场景依赖 TCP 的可靠性

关联面试题

TCP 传输过程?

  1. 连接建立:通过三次握手过程建立 TCP 连接。
  2. 数据传输:数据通过分段、确认、流量控制和拥塞控制机制传输。
  3. 连接终止:通过四次挥手过程终止 TCP 连接。

一个 tcp 连接能发几个 http 请求?

  • HTTP/1.0:每个请求需要一个新的 TCP 连接。
  • HTTP/1.1一个 TCP 连接可以发多个请求,支持持久连接和管道化
  • HTTP/2一个 TCP 连接可以并发发多个请求,通过多路复用技术优化性能。
  • HTTP/3:基于 QUIC 协议,支持多个请求和响应在一个连接上进行。

TCP是怎么判断丢包的?

TCP 有哪些手段保证可靠交付 / TCP 为什么是可靠的

TCP/IP 是如何保证数据包传输有序可靠的?

见上

说说对TCP/IP协议的了解

  1. 应用层:提供应用程序间的通信,如SMTP、FTP、Telnet等。
  2. 传输层:负责数据格式化、数据确认和丢失重传等,包括TCP和UDP。
  3. 网络层:提供基本的数据封包传送功能,如IP协议。
  4. 数据链路层:负责接收IP数据报并进行传输,管理网络媒体,如Ethernet、Serial Line等。

DNS 解析过程

image.png

DNS(Domain Name System,域名系统)解析是将域名或主机名转换为 IP 地址的过程,以便计算机能够在网络中找到目标服务器。以下是 DNS 解析的一般过程:

  1. 缓存查询

    • 查本地的 DNS 缓存
    • 向 DNS 服务器发起查询,直到找到对应的 IP 地址
  2. 递归查询

    • 本地 DNS服务 → 根 DNS → 顶级 DNS(如 .com) → 权威 DNS(如 example.com)

网络延迟和丢包

在前端面试中,网络延迟和丢包是评估你对网络传输、性能瓶颈及应对策略理解的重要考点。面试官会通过这些话题判断能否从网络层面分析问题、优化用户体验,特别是在弱网环境、移动端场景下。

一、网络延迟的考点

1. 网络延迟的构成

面试官可能会问:“用户输入 URL 后,请求延迟可能发生在哪些阶段?”

阶段含义
DNS 解析域名 → IP 地址
TCP 建立连接三次握手耗时
TLS 握手HTTPS 建立安全连接耗时
请求发送客户端发送数据
首字节返回 TTFB服务端处理 + 网络传输
内容下载响应内容下载耗时
渲染耗时浏览器解析和绘制页面

2. 常见影响网络延迟的因素

  • 地域距离:客户端与服务端物理距离大(如中国访问美国服务器)
  • DNS 缓存未命中或 DNS 配置不合理
  • TLS 握手过长(HTTPS 开销)
  • 带宽瓶颈:文件过大、网络拥堵
  • 长连接未复用(未启用 HTTP/2)
  • 移动网络抖动高(4G/5G 网络波动)
  • 首包延迟(TTFB 过高)

3. 如何优化延迟?

  • 启用 CDN,部署全球节点,减少 RTT
  • 启用 DNS 预解析:<link rel="dns-prefetch">
  • 启用 HTTP/2 或 HTTP/3,减少连接耗时
  • 减少重定向跳转、合并请求
  • 使用 preconnectprefetch 提前连接目标源
  • SSR 提前输出首屏 HTML,减少白屏
  • 缓存优化(减少服务端响应压力)

二、丢包的考点

1. 丢包的本质

网络传输中,部分数据包因链路拥堵、信号弱、硬件丢包率高等原因,未能到达目的地。

TCP:自动重传(影响性能) UDP:直接丢弃(不保证可靠)

2. 丢包导致的问题

  • 加载失败:资源文件加载中断(如 JS/CSS/图片)
  • 响应延迟:TCP 重传机制 → 等待时间增加
  • 交互卡顿:重要请求(如接口)多次丢失
  • 视频/音频卡顿:UDP 传输音视频,丢包率影响体验

3. 如何应对丢包?

  • 使用 HTTP/3(QUIC) :基于 UDP,内建重传 + 多路复用,丢包影响小
  • 合理设置超时重试机制:接口请求失败时自动重试
  • 请求兜底策略:核心数据失败后提示用户或降级
  • 断点续传/Range 请求:大文件支持分段传输
  • 服务端压缩:减少包体积,降低丢包概率
  • 尽量使用 CDN:就近分发,避免跨境链路

三、典型面试问题示例

问题涉及知识点
TTFB 高可能有哪些原因?DNS 慢、服务器响应慢、TLS 握手慢
如何应对弱网环境下的资源丢包?重试机制、HTTP/3、断点续传
TCP 丢包和 UDP 丢包的区别?TCP 重传保证可靠性,UDP 丢就丢了
为什么 HTTP/3 更适合移动端?快速建连、UDP、丢包影响小
如果某请求丢包导致加载卡顿,怎么定位?DevTools 网络请求状态、失败重试、ping/traceroute

四、总结表格

项目网络延迟丢包
本质请求往返耗时(RTT)网络数据包未能到达
表现页面加载慢、白屏、交互延迟请求失败、加载中断、视频卡顿
影响范围所有请求均可能影响重要资源或关键请求影响更明显
优化方式CDN、预连接、HTTP/2、请求合并等QUIC 协议、请求重试、兜底机制
与协议关系TCP/UDP 均有延迟TCP 可重传,UDP 丢包不可恢复
工具定位Chrome DevTools、ping、tracerouteDevTools 网络失败、Wireshark

关联面试题

TCP 和 UDP的区别是什么?

TCP是怎么判断丢包的?

TCP链接为什么会采用三次握手,而不是两次或者四次呢?

网络延迟和丢包

在前端面试中,网络延迟和丢包是评估你对网络传输、性能瓶颈及应对策略理解的重要考点。面试官会通过这些话题判断能否从网络层面分析问题、优化用户体验,特别是在弱网环境、移动端场景下。

一、网络延迟的考点

1. 网络延迟的构成

面试官可能会问:“用户输入 URL 后,请求延迟可能发生在哪些阶段?”

阶段含义
DNS 解析域名 → IP 地址
TCP 建立连接三次握手耗时
TLS 握手HTTPS 建立安全连接耗时
请求发送客户端发送数据
首字节返回 TTFB服务端处理 + 网络传输
内容下载响应内容下载耗时
渲染耗时浏览器解析和绘制页面

2. 常见影响网络延迟的因素

  • 地域距离:客户端与服务端物理距离大(如中国访问美国服务器)
  • DNS 缓存未命中或 DNS 配置不合理
  • TLS 握手过长(HTTPS 开销)
  • 带宽瓶颈:文件过大、网络拥堵
  • 长连接未复用(未启用 HTTP/2)
  • 移动网络抖动高(4G/5G 网络波动)
  • 首包延迟(TTFB 过高)

3. 如何优化延迟?

  • 启用 CDN,部署全球节点,减少 RTT
  • 启用 DNS 预解析:<link rel="dns-prefetch">
  • 启用 HTTP/2 或 HTTP/3,减少连接耗时
  • 减少重定向跳转、合并请求
  • 使用 preconnectprefetch 提前连接目标源
  • SSR 提前输出首屏 HTML,减少白屏
  • 缓存优化(减少服务端响应压力)

二、丢包的考点

1. 丢包的本质

网络传输中,部分数据包因链路拥堵、信号弱、硬件丢包率高等原因,未能到达目的地。

TCP:自动重传(影响性能) UDP:直接丢弃(不保证可靠)

2. 丢包导致的问题

  • 加载失败:资源文件加载中断(如 JS/CSS/图片)
  • 响应延迟:TCP 重传机制 → 等待时间增加
  • 交互卡顿:重要请求(如接口)多次丢失
  • 视频/音频卡顿:UDP 传输音视频,丢包率影响体验

3. 如何应对丢包?

  • 使用 HTTP/3(QUIC) :基于 UDP,内建重传 + 多路复用,丢包影响小
  • 合理设置超时重试机制:接口请求失败时自动重试
  • 请求兜底策略:核心数据失败后提示用户或降级
  • 断点续传/Range 请求:大文件支持分段传输
  • 服务端压缩:减少包体积,降低丢包概率
  • 尽量使用 CDN:就近分发,避免跨境链路

三、典型面试问题示例

问题涉及知识点
TTFB 高可能有哪些原因?DNS 慢、服务器响应慢、TLS 握手慢
如何应对弱网环境下的资源丢包?重试机制、HTTP/3、断点续传
TCP 丢包和 UDP 丢包的区别?TCP 重传保证可靠性,UDP 丢就丢了
为什么 HTTP/3 更适合移动端?快速建连、UDP、丢包影响小
如果某请求丢包导致加载卡顿,怎么定位?DevTools 网络请求状态、失败重试、ping/traceroute

四、总结表格

项目网络延迟丢包
本质请求往返耗时(RTT)网络数据包未能到达
表现页面加载慢、白屏、交互延迟请求失败、加载中断、视频卡顿
影响范围所有请求均可能影响重要资源或关键请求影响更明显
优化方式CDN、预连接、HTTP/2、请求合并等QUIC 协议、请求重试、兜底机制
与协议关系TCP/UDP 均有延迟TCP 可重传,UDP 丢包不可恢复
工具定位Chrome DevTools、ping、tracerouteDevTools 网络失败、Wireshark

DNS劫持

image.png

DNS 劫持,又称为域名劫持,是一种恶意行为,指的是攻击者通过各种手段篡改域名系统(DNS)的正常解析过程,使得用户在访问特定域名时被引导到错误的 IP 地址,从而可能导致用户访问到虚假网站、遭受信息泄露等安全问题。

工作原理

  • 篡改 DNS 服务器记录:攻击者通过入侵 DNS 服务器,直接修改服务器上的域名解析记录。例如,将正常的银行网站域名解析到一个钓鱼网站的 IP 地址,当用户访问银行网站时,就会被误导到钓鱼网站。
  • 拦截 DNS 查询请求:在用户的设备与 DNS 服务器之间的通信过程中,攻击者利用中间人攻击等方式拦截 DNS 查询请求,并返回虚假的响应,将用户引导到错误的网站。

危害

  • 信息泄露:用户可能在不知情的情况下将个人敏感信息,如账号密码、身份证号码等输入到虚假网站上,导致信息被攻击者窃取,进而造成经济损失和个人隐私泄露。
  • 恶意软件传播:用户被引导到恶意网站后,可能会自动下载并安装恶意软件,如病毒、木马等,这些恶意软件会进一步感染用户的设备,窃取更多信息或控制用户的设备。

防范措施

  • 使用可靠的 DNS 服务:选择信誉良好、安全可靠的 DNS 服务提供商,如谷歌公共 DNS、OpenDNS 等,或者使用运营商提供的默认 DNS 服务,并及时关注 DNS 服务提供商的安全公告,以获取最新的安全防护信息。
  • 安装安全软件:在设备上安装杀毒软件、防火墙等安全软件,这些软件可以检测和防范部分 DNS 劫持攻击,实时监控网络流量,发现异常的 DNS 请求和响应,并进行拦截和处理。
  • 定期更新系统和软件:及时更新操作系统、浏览器、DNS 服务器软件等,以修复可能存在的安全漏洞,降低被攻击的风险。

DNS 安全考察

威胁说明
DNS 劫持恶意篡改解析结果,用户被引导至假冒网站
DNS 投毒缓存伪造 IP,污染 DNS 服务器结果
防护措施使用 DNSSEC(域名系统安全扩展)验证响应签名;启用 HTTPS-DNS(DoH/DoT)加密 DNS 查询
DoH(DNS over HTTPS)将 DNS 查询通过 HTTPS 发送,防止被监听或篡改

DNS 缓存机制考察

缓存位置特点
浏览器缓存优先读取,缓存时间受 DNS TTL 控制
系统缓存如 macOS 的 dscacheutil、Windows 的 DNS 缓存
本地 DNS 缓存运营商提供,缓存命中高,减少外部请求

相关字段:

  • TTL(Time To Live) :DNS 记录生存时间,影响缓存有效期

DNS 查询性能优化(常考)

技术/策略说明
DNS 预获取<link rel="dns-prefetch" href="//example.com">,提前解析域名
preconnect<link rel="preconnect" href="https://example.com">,提前建立连接(包括 DNS + TCP + TLS)
缓存优化提高 DNS TTL,减少频繁解析(TTL(Time To Live) :DNS 记录生存时间,影响缓存有效期)
合理分域名访问资源避免过多不同域名导致 DNS 查询阻塞

DNS 与前端的关联考察点

关联方向说明
页面首次加载慢可能由于 DNS 查询时间长,可使用 performance.getEntriesByType('resource') 检查 DNS 时间
域名切换带来的缓存失效资源域名变化会触发新的 DNS 查询和重新建立连接
第三方资源加载慢如字体、CDN、图标等域名没有预解析
CNAME、CDN 解析过程CDN 域名背后也可能经过多次 DNS 跳转解析

面试常见问题示例

问题涉及考点
DNS 是什么?为什么需要它?基础原理
DNS 查询的完整流程是怎样的?缓存、递归与迭代查询
DNS 查询用的是哪个协议?UDP(53 端口)为主
浏览器如何优化 DNS 性能?DNS 预获取、预连接
什么是 DNS 劫持?如何防止?安全考察
DNS TTL 的作用?缓存机制与刷新间隔
为什么首次加载慢?如何判断是 DNS 问题?前端性能分析工具使用

WebSocket常见考点

WebSocket 是常考的实时通信技术,面试官通常会从其原理、与 HTTP 的关系、使用方式、应用场景、安全性、性能优化等方向进行考察。以下是系统整理的 WebSocket 考察点大全


一、基础概念考察

考察点要点
WebSocket 是什么?是一种基于 TCP 的全双工通信协议,用于客户端与服务端建立持久连接
解决了什么问题?解决了 HTTP 无法实现真正实时通信、轮询/长轮询开销大的问题
属于哪一层协议?基于 TCP 之上的应用层协议,协议名称是 ws://(或加密的 wss://

二、与 HTTP 的关系

考察点要点
如何建立连接?使用 HTTP 协议的 Upgrade 机制 进行握手,成功后协议变为 WebSocket
建立连接过程客户端发起包含 Upgrade: websocket 的请求,服务端返回 101 Switching Protocols
与 HTTP 的区别HTTP 是 单向请求响应,WebSocket 是 双向持续通信
与 HTTP/2 的区别WebSocket 不能直接复用 HTTP/2,需要独立连接

三、使用与 API 考察

考察点要点
WebSocket 创建方式const socket = new WebSocket('ws://example.com')
常用事件onopenonmessageoncloseonerror
发送数据socket.send(data)
关闭连接socket.close(code, reason)
消息格式支持字符串、BlobArrayBuffer 等格式

四、应用场景考察

场景原因
实时聊天、弹幕、在线游戏高实时性,低延迟
股票、彩票、竞价系统实时数据推送
协同编辑(如在线文档)多端状态同步
物联网设备通讯双向通信能力

五、与其他通信方案对比

特性HTTP 轮询SSE(Server-Sent Events)WebSocket
双向通信✅ 是
单连接复用❌ 否✅ 是(只接收)✅ 是(双向)
延迟性能✅ 低(最快)
浏览器兼容性✅ 普遍支持部分旧版 IE 不支持✅ 普遍支持
断线重连❌ 需手动实现✅ 内建支持❌ 需手动实现或封装处理

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

在 WebSocket 协议出现以前,创建一个和服务端进双通道通信的 web 应用,需要依赖HTTP协议,进行不停的轮询,这会导致一些问题:

  • 服务端被迫维持来自每个客户端的大量不同的连接
  • 大量的轮询请求会造成高开销,比如会带上多余的header,造成了无用的数据传输。

http协议本身是没有持久通信能力的,但是我们在实际的应用中,是很需要这种能力的,所以,为了解决这些问题,WebSocket协议由此而生,于2011年被IETF定为标准RFC6455,并被RFC7936所补充规范。

并且在HTML5标准中增加了有关WebSocket协议的相关api,所以只要实现了HTML5标准的客户端,就可以与支持WebSocket协议的服务器进行全双工的持久通信了。


六、断线重连与心跳机制

考察点

  • 为什么需要心跳? → 检测客户端是否在线,防止中间网络断开但不通知

  • 如何实现?

    • 客户端定时发送 "ping" 或自定义心跳包
    • 服务端超时未收到则断开连接
  • 断线重连策略

    • 实现自动重连(如指数退避重连)
    • 避免频繁重连导致服务器压力过大

七、安全性考察

考察点要点
加密版本使用 wss://(相当于 HTTPS),基于 TLS 加密
身份认证一般通过握手时携带 token/cookie 完成认证
跨域支持默认支持跨域(同源限制不严格)
被动关闭连接网络断开、浏览器关闭页面、服务器断开
DoS 防护服务端需做连接数限制和身份验证,防止连接滥用

八、服务端实现方案(了解为加分项)

技术特点
Node.js + ws简单、适合轻量服务
Socket.io封装了 WebSocket,支持断线重连、fallback、事件系统
Go / Java / Python多种语言有成熟框架

九、面试常见问题示例

问题考察方向
WebSocket 如何建立连接?握手流程、Upgrade
WebSocket 与 HTTP 的区别?通信模式、连接状态
WebSocket 有哪些使用场景?实时应用、双向通信
如何处理 WebSocket 的断线重连重连机制、心跳包
WebSocket 如何鉴权?握手参数、token 认证
WebSocket 与 SSE 有何区别?单向 vs 双向、兼容性

关联面试题

介绍下WebSocket

WebSocket 中的心跳是为了解决什么问题?

说说对 WebSocket 的了解

webSocket 有哪些安全问题,应该如何应对?

说说WebSocket和HTTP的区别

说下 websocket 的连接原理

WebSocket协议的底层原理、与HTTP的区别

WebSocket 协议底层原理

WebSocket 协议的核心目标是在浏览器和服务器之间建立持久的、全双工的通信连接,其底层原理可从以下几个阶段来理解:

1. 握手阶段
  • 客户端发起请求客户端通过发送一个特殊的 HTTP 请求到服务器,请求将当前的 HTTP 连接升级为 WebSocket 连接。这个请求的 HTTP 头中包含了一些关键信息,例如:

    • Upgrade: websocket:表明客户端希望将协议升级为 WebSocket
    • Connection: Upgrade:表示要进行协议升级。
    • Sec - WebSocket - Key:是一个经过 Base64 编码的随机值,用于验证服务器响应的合法性
    • Sec - WebSocket - Version:指定了客户端支持的 WebSocket 版本。
  • 服务器响应:服务器接收到请求后,会对请求头进行检查如果服务器支持 WebSocket 协议,就会返回一个状态码为 101 Switching Protocols 的 HTTP 响应,表示同意升级连接。响应头中也包含了一些关键信息:

    • Upgrade: websocket 和 Connection: Upgrade:确认协议升级。
    • Sec - WebSocket - Accept:是服务器根据客户端发送的 Sec - WebSocket - Key 计算得出的值,用于客户端验证服务器响应的合法性。
2. 数据传输阶段
  • 帧格式:握手成功后,连接就从 HTTP 升级为 WebSocket,数据以帧(Frame)的形式在客户端和服务器之间传输。每个 WebSocket 帧包含一个帧头和一个帧体
  • 全双工通信:客户端和服务器可以在这个连接上独立地、同时地发送和接收数据,实现了真正的全双工通信。双方无需等待对方的响应就可以随时发送新的数据。
3. 关闭连接阶段
  • 发送关闭帧:当一方希望关闭连接时,会发送一个关闭帧给对方。关闭帧中包含了关闭的状态码和可选的关闭原因。
  • 响应关闭帧:另一方收到关闭帧后,通常会发送一个确认关闭帧作为响应,然后双方关闭底层的 TCP 连接。

WebSocket 与 HTTP 的区别

1. 连接特性
  • HTTP无状态的、短连接协议。每次客户端向服务器发送请求时,都需要建立一个新的 TCP 连接,请求处理完成后,连接就会关闭。这意味着每次请求都需要重新进行 TCP 握手,开销较大。
  • WebSocket有状态的、长连接协议。在握手成功后,连接会一直保持打开状态,直到一方主动关闭。这避免了频繁建立和关闭连接的开销,提高了通信效率。
2. 通信模式
  • HTTP半双工通信,同一时间内数据 只能单向传输,要么是客户端向服务器发送请求,要么是服务器向客户端发送响应。客户端必须等待服务器的响应后才能发起新的请求。
  • WebSocket全双工通信,客户端和服务器可以同时向对方发送数据,实现了实时的双向通信,无需等待对方的响应
3. 数据传输效率
  • HTTP:每次请求和响应都需要携带完整的 HTTP 头信息,即使传输的数据量很小,也会有较大的额外开销。而且HTTP 请求和响应通常是基于文本的,传输效率相对较低。
  • WebSocket:在握手阶段后,数据传输只需要包含少量的帧头信息,减少了额外开销。同时,WebSocket 支持二进制数据传输,对于一些需要传输大量数据的场景(如视频、音频等),效率更高。
4. 应用场景
  • HTTP:适用于传统的 Web 页面请求、文件下载等场景,主要用于一次性的请求 - 响应交互。
  • WebSocket:更适合实时性要求高的场景,如在线聊天实时数据推送(如股票行情实时天气预报等)、多人游戏、实时监控等。

详细讲解WebSocket协议

1. WebSocket的本质

  • 双向实时通信协议与HTTP的"请求-响应"模式不同,WebSocket建立持久化全双工连接,支持服务端主动推送数据。
  • 协议升级机制:通过HTTP握手(Upgrade头)切换到WebSocket协议(ws://wss://)。
  • 低延迟传输:基于TCP,但避免HTTP头重复传输,减少数据包体积。

2. 关键优势

特性传统HTTPWebSocket
连接模式短连接,单向请求长连接,双向通信
头部开销每次请求携带完整Header初始握手后仅传输数据帧
实时性依赖轮询(高延迟)毫秒级推送
服务器主动推送不支持原生支持
适用场景静态资源获取实时交互应用

与替代方案对比

技术协议方向复杂度适用场景
WebSocketTCP双向实时双向交互
SSEHTTP单向服务端到客户端推送
长轮询HTTP半双工兼容性要求高的场景
WebRTCUDP双向音视频流传输

WebSocket已成为现代实时Web应用的基石技术,日均处理数十亿连接。掌握其原理和最佳实践,是构建高性能实时系统的关键能力。

介绍一下 Service Worker ⭐️⭐️

service worker是PWA的重要组成部分,W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存,也是Web Worker的升级版

Service worker (简称 SW) 是一个注册在指定源和路径下的事件驱动 Worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是网络不可用)下的表现。

定义与作用

  • 后台脚本:Service Worker是浏览器后台独立于主线程之外的工作线程
  • 网络代理:可拦截和处理网络请求资源缓存离线访问
  • 事件驱动:响应推送通知、后台同步等事件,增强Web应用功能。

Service Worker 的缓存机制是通过缓存 API 实现的,它允许开发者拦截和缓存 HTTP 请求,以提高离线体验和加速页面加载。以下是 Service Worker 缓存 HTTP 请求资源的基本流程和原理:

1. 注册 Service Worker

首先,Service Worker 需要在浏览器中注册。通常在主线程(如 JavaScript 入口文件)中进行注册:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js')
    .then(registration => {
      console.log('Service Worker registered with scope:', registration.scope);
    })
    .catch(error => {
      console.error('Service Worker registration failed:', error);
    });
}

2. 安装 Service Worker

在 Service Worker 脚本中,首先会触发 install 事件。在这个事件中,可以预缓存一些资源,以便在 Service Worker 激活后立即可用

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache-v1').then(cache => {
      return cache.addAll([
        '/',
        '/styles/main.css',
        '/scripts/main.js',
        '/images/logo.png'
      ]);
    })
  );
});

3. 激活 Service Worker

activate 事件在 Service Worker 安装完成后触发。可以在这个事件中进行缓存清理,删除旧的缓存

self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.filter(cacheName => {
          // 这里可以指定要删除的缓存
          return cacheName !== 'my-cache-v1';
        }).map(cacheName => {
          return caches.delete(cacheName);
        })
      );
    })
  );
});

4. 拦截和缓存请求

fetch 事件允许 Service Worker 拦截所有的网络请求。可以根据需要从缓存中返回资源,或将请求转发到网络:

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cachedResponse => {
      // 如果缓存中有匹配的资源,直接返回
      if (cachedResponse) {
        return cachedResponse;
      }

      // 否则,发起网络请求
      return fetch(event.request).then(response => {
        // 克隆响应对象,因为响应只能被消费一次
        const responseClone = response.clone();

        // 将网络请求的结果缓存
        caches.open('my-cache-v1').then(cache => {
          cache.put(event.request, responseClone);
        });

        return response;
      });
    }).catch(() => {
      // 网络和缓存都失败的情况
      return new Response('Oops, something went wrong.');
    })
  );
});

5. 资源管理

  • 缓存清理定期删除过期或不再需要的缓存,保持缓存的健康状态
  • 缓存策略可以实现不同的缓存策略,如缓存优先、网络优先、缓存和网络同时等

Web Workers常见考点

1. Web Workers 的基本概念

  • 定义Web Workers 是运行在后台的独立线程,允许在不阻塞主线程的情况下执行脚本代码
  • 类型:常见的有 Dedicated Workers(专用 Workers,单页面使用)和 Shared Workers(共享 Workers,多个页面或同源脚本共享)。

2. 如何创建和使用 Web Worker

  • Worker 创建

    • 通过 new Worker() 创建 Worker 线程,传入一个 JavaScript 文件的路径作为参数。
    const worker = new Worker('worker.js');
    
  • 消息通信

    • 主线程通过 postMessage() 向 Worker 发送消息,Worker 通过 onmessage 事件处理消息并返回处理结果:
    // 主线程
    worker.postMessage('Hello Worker!');
    worker.onmessage = function(event) {
        console.log('Received from worker:', event.data);
    };
    
    // worker.js
    self.onmessage = function(event) {
        console.log('Received from main thread:', event.data);
        self.postMessage('Message received');
    };
    

3. Web Workers 的特性

  • 异步执行Web Workers 运行在独立线程中,与主线程并行,不会阻塞主线程的 UI 渲染或事件处理。
  • 不共享上下文:Worker 没有访问 DOM、window、document 等浏览器对象的权限,运行在独立的全局作用域中(self 对象)。
  • 通信机制:主线程与 Worker 通过 postMessage() 传递消息,消息是通过串行化传递的,数据不会共享,而是复制。
  • 支持的 API:Worker 支持的 API 有 XMLHttpRequestfetchsetTimeoutsetIntervalWebSocketsimportScripts(),但不支持 DOM 操作。

4. Web Workers 的使用场景

  • CPU 密集型任务:如复杂的数学计算、大量数据处理、图片和视频处理等,可以放到 Worker 中执行,避免主线程被阻塞
  • 异步数据处理如后台处理 API 响应、大型 JSON 解析、加密解密等任务,保证 UI 的流畅性。
  • 离线应用中的数据同步:通过 Web Workers 处理离线数据的同步与缓存,保证数据一致性。

5. Web Workers 与多线程的区别

  • Worker 是单线程的:每个 Web Worker 是独立的单线程,多个 Worker 可以并行执行任务,但 Worker 本身并没有真正的多线程能力 (不会共享状态)。
  • 多 Worker 协作:可以通过创建多个 Worker 实现伪多线程,通过消息传递共享数据。

6. Shared Worker 的特点

  • 共享 Worker 线程:不同的浏览器窗口、iframe 等在同一页面中可以共享一个 Worker 线程,适用于跨多个页面协作的场景
  • 通信方式:与专用 Worker 类似,但不同页面之间可以通过 MessagePort 进行通信。

7. Worker 中的错误处理

  • 主线程错误处理:主线程可以通过 onerror 事件捕获 Worker 中的错误。
worker.onerror = function(error) {
    console.log('Error in worker:', error.message);
};
  • Worker 内的错误捕获:Worker 内部可以使用 try-catch 捕获代码执行中的错误。

8. Web Workers 的生命周期管理

  • 终止 Worker:可以通过** terminate() **方法在主线程中手动终止 Worker。
worker.terminate();
  • 自动销毁:Worker 执行完成后不会自动销毁,仍然可以保持活跃等待进一步的消息,因此需要手动管理 Worker 的生命周期以释放资源。

9. Web Workers 的性能优化

  • 线程开销:创建 Worker 线程有一定的开销,过多的 Worker 可能会增加性能负担,尤其是在短时间内频繁创建和销毁 Worker 的场景。
  • 消息传递的成本:由于消息是通过拷贝传递的,大量数据传递会带来性能开销。可以通过使用 Transferable Objects 来优化数据传输。

10. Transferable Objects

  • 特点:Transferable Objects 允许直接将数据的所有权转移给 Worker,而不是复制数据。常用于 ArrayBuffer 等大数据传输的场景,提升性能。
let buffer = new ArrayBuffer(1024);
worker.postMessage(buffer, [buffer]);

11. Service Workers 与 Web Workers 的区别

  • 作用不同:Web Workers 用于在后台执行计算密集型任务,主要是数据处理;Service Workers 则用于控制网络请求、缓存管理、离线支持等。
  • 生命周期不同:Service Workers 在用户首次访问页面时注册后一直存在,即使关闭页面也能继续运行;而 Web Workers 只在页面活跃时存在。

12. Web Workers 的兼容性

  • 需要了解 Web Workers 在不同浏览器中的兼容性,尤其是在移动端或旧版本浏览器中的支持情况。

13. Worker 线程中的模块化脚本加载

  • importScripts() :Web Workers 支持使用 importScripts() 同步加载外部脚本,考察点可能包括如何使用该方法来分割代码或动态加载代码。
importScripts('script1.js', 'script2.js');

14. Worker 内的 API 支持

  • 支持的 API:如 Web Workers 支持的部分 API(如 fetchWebSocketssetTimeoutXMLHttpRequest),如何在 Worker 内使用这些 API。
  • 不支持的 API:如 DOM 操作、alert() 等不支持的操作,考察点可能包括 Worker 的使用限制。

关联面试题

Web Worker 是什么?

WebWorker、SharedWorker 和 ServiceWorker 有哪些区别?

正向代理和反向代理常见考点

“正向代理”和“反向代理”是前端与网络交叉领域的高频考察点,涉及网络请求过程、安全控制、架构设计、前端跨域处理等多个方面。

一、基础定义(核心区别)

类型代理对象作用方位用户是否感知
正向代理客户端 → 服务端客户端访问外部资源
反向代理服务端 → 客户端服务端代理多个后端

二、举例理解

  • 正向代理:你无法直接访问被墙的 google.com,通过代理服务器 proxy.com 访问,proxy.com 再去请求 google.com 并返回结果给你。

    • 常用于:翻墙、隐匿用户身份、访问受限资源
  • 反向代理:你访问 api.example.com,请求先到反向代理服务器(如 Nginx),再转发到真正的后端服务(如 node1.internal)。

    • 常用于:负载均衡、缓存、统一鉴权、隐藏服务结构

三、典型面试考察点

1. 正向代理考察点

点位要点
作用客户端通过代理访问目标资源
应用场景翻墙、匿名访问、突破访问限制(如公司内网限制访问外网)
原理客户端将目标地址请求发给代理 → 代理向目标服务器请求 → 返回结果给客户端
实现方式浏览器配置代理地址,或使用程序设置代理
安全性会暴露目标地址,用户身份可能被记录

2. 反向代理考察点

点位要点
作用客户端访问代理服务器,由代理向真实服务请求
应用场景负载均衡、服务聚合、缓存加速、安全防护、隐藏内部服务
原理客户端只知道代理地址,代理内部根据路径、策略转发请求
实现方式使用** Nginx、Apache、Node.js** 等配置反向代理规则
安全性屏蔽真实服务地址,方便统一鉴权和防护(如 DDOS)

四、与前端的关系

考察方向说明
跨域处理本地开发环境通过 devServer.proxy 或 Nginx 设置反向代理 → 绕过 CORS
资源访问加速前端资源或 API 接口通过反向代理 CDN/缓存节点加速
统一接口转发前端请求统一发给一个网关地址,网关做反向代理路由分发
SSR 渲染前端请求 SSR 服务 → 反向代理渲染结果页面返回

五、常见面试问题

面试问题涉及知识点
正向代理和反向代理的区别?代理方向、用户是否感知、应用场景
为什么前端开发时使用反向代理可以解决跨域问题?跨域绕过原理、同源策略
如何使用 Nginx 设置反向代理?Nginx 配置规则
服务端如何实现接口聚合?反向代理网关分发请求
如何隐藏真实服务地址?利用反向代理统一出口
CDN 是正向代理还是反向代理?反向代理(常考陷阱题) ,CDN 面向用户,但代理的是服务器资源

六、配套场景理解

  • Nginx 配置反向代理示例:

    location /api/ {
      proxy_pass http://backend-server/;
      proxy_set_header Host $host;
    }
    
  • Webpack DevServer 开发时的代理设置(前端 CORS 绕过):

    devServer: {
      proxy: {
        '/api': {
          target: 'http://localhost:3000',
          changeOrigin: true,
        },
      }
    }
    

七、扩展考点

扩展点说明
CDN 是否属于代理属于反向代理(缓存 + 加速)
网关与反向代理的区别网关具备更强的逻辑、鉴权、路由能力
微服务架构中反向代理的作用服务聚合、统一入口、灰度发布等
TLS 终止代理Nginx 处理 SSL,后端走明文 HTTP,简化后端服务配置

关联面试题

正向代理和反向代理分别是什么?

网络性能优化常见考点

前端“网络层面的性能优化”是高频面试考点,涵盖了从资源加载、缓存、连接管理,到协议选择等多个方向。面试时往往从“用户输入 URL 到页面加载”这条链路入手,考查在网络传输环节提升页面性能的能力。

1. DNS 优化

  • 使用 DNS 预解析(<link rel="dns-prefetch">
  • 减少跨域请求
  • 使用 CDN 降低解析延迟
  • 减少 DNS 查询频次(共享域名)

2. TCP/TLS 连接优化

  • 连接复用(Keep-Alive、HTTP/2 多路复用)
  • 减少重定向次数
  • 减少第三方域名连接数(避免多次三次握手)
  • TLS1.3 优化握手过程

3. HTTP 协议优化

  • 使用 HTTP/2:

    • 多路复用(消除队头阻塞)
    • 头部压缩
    • Server Push(预加载资源)
  • 使用 HTTP/3:

    • 基于 QUIC,减少握手延迟

4. 缓存策略优化

  • 强缓存:Cache-Control: max-ageExpires
  • 协商缓存:ETag / Last-Modified
  • CDN 缓存策略
  • 静态资源使用 hash 文件名(内容变动才刷新)

5. 资源加载优化

  • 懒加载:图片、视频等资源按需加载(loading="lazy"

  • 预加载 & 预请求:

    • <link rel="preload">
    • <link rel="prefetch">
  • 按需加载模块(JS/CSS)

6. 压缩与传输优化

  • 启用 Gzip 或 Brotli 压缩文本资源
  • 图片压缩优化(WebP、AVIF)
  • 雪碧图、SVG 精简、字体子集
  • 减少重复包体(第三方库抽离 CDN)

7. 请求合并与去重

  • 合并资源:CSS、JS 打包合并(仅适用于 HTTP/1.1)
  • 使用图标字体 / 雪碧图减少请求
  • GraphQL 替代多个 REST 请求

8. 首屏优化

  • 关键资源优先加载(CSS、字体、JS)
  • SSR + Hydration 提高 TTFB
  • Skeleton + Lazy Render 提高首屏体验
  • Critical CSS 提前内联

9. 使用 CDN 加速

  • 静态资源分发到最近节点
  • 减少回源次数、提高命中率
  • 自定义缓存配置策略

10. Service Worker 与离线缓存

  • 用于缓存页面资源与接口数据
  • 提高重复访问性能
  • 提供离线能力(PWA)

11. 性能指标与监控

  • TTFB(首字节时间)
  • FCP、LCP、FID(核心 Web Vitals)
  • Resource Timing API、Navigation Timing API
  • 使用 Lighthouse、WebPageTest、Chrome DevTools 分析

面试常见问题示例

面试题方向具体示例问题
网络优化策略页面加载慢,网络层如何优化?
协议选择HTTP/2 带来哪些性能提升?
缓存优化强缓存和协商缓存的优先级?
压缩优化Brotli 与 Gzip 有哪些不同?
请求优化怎么减少第三方资源带来的性能影响?
首屏优化如何优化首屏加载时间?SSR 有哪些作用?

关联面试题

想要实现页面加载速度提升(性能优化),可以从哪些方向来尝试?

前端性能优化指标有哪些?怎么进行性能检测?

说说常规的前端性能优化手段

从输入URL到页面加载全过程(6个步骤)

1.DNS 域名解析
2.建立连接 (TCP/UDP)
3.发送 HTTP 请求
4.响应 HTTP 请求(这之前服务器一般要处理请求 )
5.页面渲染
6.关闭连接

image.png

URL 解析

  • 浏览器首先会对输入的 URL 进行解析,将其分解为(5个部分)协议(如 HTTP、HTTPS)域名(如www.example.com)、端口号(若未指定则使用默认端口,如 HTTP 默认 80 端口,HTTPS 默认 443 端口)、路径(如 /index.html)、查询参数(如?param1=value1&param2=value2)等部分。

image.png

1.DNS 域名解析

  1. 浏览器缓存查询
  2. 操作系统缓存查询
  3. hosts 文件查询
  4. 本地 DNS 服务器(ISP 提供)查询
  5. 根域名服务器(..)返回顶级域名服务器地址
  6. 顶级域名服务器返回权威域名服务器地址
  7. 权威域名服务器返回目标域名对应 IP
  8. 本地 DNS 服务器将结果缓存并返回

递归查询 与 迭代查询

  • 递归查询:客户端向本地 DNS 请求,期望拿到最终 IP,其他查询步骤由 DNS 服务器完成。
  • 迭代查询:DNS 服务器自己一步步查找其他服务器来获取结果。

image.png

2.建立TCP连接

  • 获得服务器 IP 地址后,浏览器会根据协议与服务器建立连接。对于 HTTP/1.x 和 HTTP/2 协议,通常使用 TCP 连接;对于 HTTP/3 协议,则使用 UDP 连接(基于 QUIC 协议)。
  • 在建立 TCP 连接时,会通过三次握手来确保连接的可靠性。客户端发送一个 SYN 包,服务器收到后回复一个 SYN-ACK 包,客户端再发送一个 ACK 包,至此连接建立成功。

image.png

3.发送 HTTP 请求

  • 连接建立后,浏览器会构建 HTTP 请求消息,并将其发送到服务器。请求消息包括请求行(包含请求方法,如 GET、POST 等,以及请求的 URL 和 HTTP 版本)、请求头(包含各种字段,如 User - Agent、Accept、Cookie 等,用于传递客户端的信息和请求相关的参数)和请求体(如果是 POST 请求,会包含提交的数据)。

image.png

4.响应 HTTP 请求

  • 浏览器接收服务器返回的 HTTP 响应消息。响应消息包括状态行(包含 HTTP 版本、状态码、状态描述,如 200 OK、404 Not Found 等)、响应头(包含服务器信息、内容类型、缓存控制等字段)和响应体(包含请求的资源内容,如 HTML、CSS、JavaScript 文件,或者图片、视频等二进制数据)。

image.png

5.页面渲染

  • 浏览器根据响应体中的内容进行页面渲染。如果响应内容是 HTML,浏览器会首先解析 HTML 文件,构建 DOM(文档对象模型)树。在解析过程中,遇到 CSS 样式表和 JavaScript 脚本等资源,会同时发起请求去获取这些资源。
  • 浏览器解析 CSS 样式表,构建 CSSOM(CSS 对象模型)树,然后将 DOM 树和 CSSOM 树合并成渲染树(Render Tree)。渲染树只包含需要显示的元素及其样式信息。
  • 浏览器根据渲染树进行布局(Layout),计算出每个元素在页面中的位置和大小。然后进行绘制(Paint),将元素的样式绘制到屏幕上,最终呈现出用户看到的页面。

image.png

6.连接关闭

  • 页面加载完成后,根据不同的情况,连接可能会被关闭或者保持一段时间以便后续的请求复用。对于 HTTP/1.x,如果设置了 Connection: keep - alive连接会在一定时间内保持打开,以便浏览器可以继续请求其他资源;如果没有设置或者超时时间到了,连接会被关闭。对于 HTTP/2 和 HTTP/3,连接通常会被更有效地复用,以提高性能。

关键事件与性能指标

事件触发时机优化意义
DOMContentLoadedHTML 和同步 JS 解析完成可尽早执行交互逻辑
load所有资源(图片、样式表)加载完成标记页面完全加载
First Paint (FP)首次渲染(背景色、边框等)用户感知加载开始
First Contentful Paint (FCP)首次文本或图像内容渲染核心内容可见性
Largest Contentful Paint (LCP)最大内容元素渲染完成衡量加载性能的关键指标
Time to Interactive (TTI)页面可交互(事件监听已绑定)用户体验流畅度

优化策略

  1. 网络层优化

    • 启用 HTTP/2 或 HTTP/3,使用 CDN 加速静态资源。
    • 资源压缩(Brotli/Gzip)、图片懒加载、域名分片(HTTP/1.1)。
  2. 渲染层优化

    • 减少重排(Reflow)与重绘(Repaint),使用 requestAnimationFrame
    • 异步加载非关键 CSS/JS,延迟加载第三方脚本。
  3. 缓存策略

    • 静态资源设置长期强缓存(max-age=31536000),动态内容使用协商缓存。
  4. 预加载技术

    • 使用 preloadprefetchpreconnect 提前获取关键资源。

总结

从 URL 输入到页面展示的完整链路涉及 网络协议栈、浏览器引擎、渲染管线 的协同工作。理解各环节的阻塞点和优化手段(如减少 DNS 查询、压缩资源、避免渲染阻塞)是提升 Web 性能的关键。通过 Chrome DevTools 的 Performance 面板可深入分析各阶段耗时,针对性优化关键路径。

浏览器渲染过程中的网络层面常见考点

浏览器渲染过程中,网络层面的考察重点主要集中在从用户输入 URL 到页面渲染完成之间的网络通信过程。这个环节涉及多个关键阶段,是前端性能优化、资源加载、安全和协议理解的核心。

一、从输入 URL 到页面渲染的网络流程(宏观流程)

  1. DNS 解析

    • 浏览器如何查找域名的 IP?
    • 是否存在 DNS 缓存?本地 DNS / 操作系统 / 浏览器级缓存?
    • 如何减少 DNS 请求?
  2. TCP 连接建立

    • 三次握手的过程
    • 建立连接的时机
    • TCP 连接重用(如 HTTP/1.1 的 Keep-Alive)
  3. TLS/SSL 握手(HTTPS)

    • HTTPS 建立过程(涉及证书验证、对称加密密钥协商)
    • 为什么 HTTPS 比 HTTP 慢?
    • TLS 握手和性能优化(如 TLS 1.3 减少 RTT)
  4. HTTP 请求发送

    • 请求方法(GET/POST)和状态码
    • 请求头部(如 Cookie、User-Agent、Accept-Encoding 等)
    • 请求体的构造
  5. 服务器响应

    • 响应码(200、304、404、500…)
    • 响应头(Content-Type、Cache-Control、Set-Cookie…)
    • 响应体(HTML、JS、CSS、图片等)
  6. 内容传输

    • 是否启用了压缩(如 gzip/br)
    • 分块传输(Transfer-Encoding: chunked)
    • Range 请求、断点续传
  7. 连接关闭或复用

    • HTTP1.1 中的 Keep-Alive
    • HTTP/2 的多路复用(连接复用机制)

二、关键协议层考察点

1. DNS 相关

  • DNS 解析过程、递归查询、权威解析器
  • DNS PrefetchPreconnect 优化手段
  • 使用 CDN 时的 DNS 解析流程

2. HTTP 协议细节

  • HTTP1.0 vs HTTP1.1 vs HTTP2 vs HTTP3
  • 请求/响应头详解
  • 连接管理、流水线机制、队头阻塞(HTTP1.1)问题
  • HTTP 缓存机制(协商缓存 & 强缓存)

3. HTTPS 及 TLS

  • TLS 1.2 / 1.3 的握手流程
  • CA 证书信任体系
  • HSTS、OCSP Stapling、安全配置

三、网络性能优化相关考点

  • 如何减少网络请求?
  • 如何优化 DNS 查询?
  • 如何利用缓存减少加载时间?
  • TCP/TLS 握手成本如何优化?
  • 使用 CDN 的原理和优势
  • 静态资源压缩与合并(如 JS/CSS/images)
  • 资源预加载策略:<link rel="preload">prefetchdns-prefetch 等

四、资源加载相关

  • 浏览器加载静态资源的顺序?
  • JS/CSS 加载是否阻塞渲染?
  • defer 和 async 的区别
  • 图片懒加载、字体加载策略
  • Service Worker 的作用与资源拦截能力

五、安全相关

  • Mixed Content(HTTPS 页面加载 HTTP 资源)问题
  • HSTS 强制使用 HTTPS
  • CORS 跨域通信过程
  • CSP(内容安全策略)防止 XSS 注入

六、面试常见问题

  1. 浏览器从输入 URL 到页面显示,网络阶段都做了什么?
  2. TCP 三次握手、四次挥手过程?
  3. HTTPS 是如何建立安全连接的?
  4. HTTP/2 如何实现多路复用?
  5. 如何通过缓存优化首屏加载时间?
  6. DNS 查询过程是怎样的?如何优化?
  7. HTTP 状态码中,301、302、304 各代表什么?
  8. 如何避免 DNS 重复解析?
  9. 浏览器对静态资源请求做了哪些优化?
  10. 如何配置服务器响应头以实现资源缓存策略?
模块关注点
DNS查询过程、缓存策略、CDN 影响
TCP/TLS握手流程、连接复用、性能影响
HTTP 协议各版本特性、缓存机制、状态码
HTTPS 安全证书验证、加密机制、防中间人攻击
资源加载与性能压缩、缓存、连接优化、加载顺序、预加载策略
安全与跨域CORS、HSTS、CSP、Cookie 安全属性等

关联面试题

HTTP/2 如何实现多路复用

HTTP/2 基于单个 TCP 连接,通过 二进制帧 + 流 的核心机制实现多路复用,核心逻辑 3 点:

  1. 数据拆分为二进制帧摒弃 HTTP/1.1 的文本格式,将请求 / 响应的所有数据拆成小块 二进制帧,每个帧都标记所属的 流 ID
  2. 流的并行传输与独立标识每个请求 / 响应对应一个独立的 ,拥有唯一 流ID。同一 TCP 连接上,多个流的帧可以乱序传输,互不干扰。
  3. 接收端重组服务端 / 客户端根据帧的 流ID 识别归属,将乱序的帧重新组装成完整的请求或响应,实现多个请求并行处理。

简单说:一个 TCP 连接,多个流并行传输帧,解决了 HTTP/1.1 连接数限制和队头阻塞问题

如何通过缓存优化首屏加载时间?

核心是最大化复用缓存资源,减少首屏请求数量和体积,简单说 4 点:

  1. 强缓存静态资源给 JS/CSS/ 图片等配置 Cache-Control: public, max-age=31536000 长期缓存,配合内容哈希命名(如 app.abc123.js),内容不变则缓存永久有效,首屏直接读本地缓存。
  2. 预缓存核心资源用 link rel="preload" 预加载首屏关键资源(如核心 JS、字体),用 link rel="preconnect" 提前建立 CDN 连接,减少 DNS/TCP 握手耗时。
  3. 协商缓存 HTML首屏 HTML 设 Cache-Control: no-cache + ETag,每次请求先验证是否更新,未更新则返回 304,避免重复下载完整 HTML。
  4. 利用 Service Worker 缓存离线缓存首屏核心资源(HTML/JS/CSS),二次访问直接从缓存读取,彻底跳过网络请求。

如何避免 DNS 重复解析

核心是减少 DNS 解析次数、复用已有解析结果,简单说 3 种常用方法:

  1. 利用浏览器 DNS 缓存:浏览器会缓存域名解析结果(默认几十秒到几分钟),尽量让静态资源(JS/CSS/ 图片)部署在同一域名(或同一主域) ,避免频繁解析不同域名。

  2. 预解析 DNS 连接:在 HTML 头部添加 preconnectdns-prefetch,提前解析后续要用到的域名,避免后续请求阻塞等待 DNS 解析:

    <!-- 预建立连接(推荐,不仅解析DNS,还建立TCP/SSL握手) -->
    <link rel="preconnect" href="https://cdn.example.com">
    <!-- 仅预解析DNS(兼容低版本浏览器) -->
    <link rel="dns-prefetch" href="https://cdn.example.com">
    
  3. 使用 CDN 统一域名:将所有静态资源部署到同一个 CDN 域名下,或使用通配符域名,减少不同域名的解析开销;同时避免不必要的跨域域名请求。

浏览器对静态资源请求做了哪些优化

浏览器内置多种优化策略,核心围绕减少请求、提升并行、复用资源,主要有这几点:

  1. 请求优化

    • 「并行请求」:HTTP/1.1 支持同一域名下同时发起多个并行请求(默认 6 个左右),避免单个请求阻塞所有资源;HTTP/2 则通过多路复用实现更高效率的并行。
    • 「请求合并」:自动合并部分同源小资源请求(也可通过前端打包工具辅助合并,如 Webpack 打包 JS/CSS)。
    • 「请求优先级」:优先加载首屏关键资源(如 HTML、核心 JS/CSS),延后加载非首屏资源(如图片、异步组件)。
  2. 缓存优化

    • 「多级缓存」:依次读取内存缓存 → 磁盘缓存 → 网络请求,复用已缓存的静态资源,避免重复下载。
    • 「DNS 缓存」:缓存域名解析结果,减少重复 DNS 查询开销。
    • 「协商缓存复用」:缓存未过期时,通过 ETag/Last-Modified 验证资源,返回 304 不传输完整资源。
  3. 其他优化

    • 「资源预加载 / 预渲染」:支持 preload(预加载关键资源)、prefetch(预加载后续页面资源)。
    • 「自动压缩解压」:自动识别并解压 gzip/Brotli 压缩的资源,减少传输体积。
    • 「避免无效请求」:缓存 404/500 等错误响应(短时间),避免重复请求不存在的资源。

如何配置服务器响应头以实现资源缓存策略

Nginx 为例(最常用),核心是通过 add_header 配置缓存相关响应头,区分「静态资源强缓存」和「核心文件协商缓存」,配置如下:

  1. 核心配置原则

    • 静态资源(JS/CSS/ 图片 / 字体):配置「强缓存」,减少网络请求;
    • 核心文件(HTML / 动态接口):配置「协商缓存」,保证资源新鲜度。
  2. 具体 Nginx 配置代码

    server {
      listen 80;
      server_name example.com;
      root /usr/share/nginx/html; # 项目部署目录
    
      # 1. 静态资源:强缓存(1年有效期,长期复用)
      location ~* .(js|css|png|jpg|jpeg|gif|ico|woff|woff2)$ {
        # 强缓存核心响应头(优先级最高)
        add_header Cache-Control "public, max-age=31536000, immutable";
        # 兼容 HTTP 1.0,配合 Cache-Control
        expires 1y;
        # 开启 gzip 压缩,减小传输体积
        gzip on;
      }
    
      # 2. HTML 文件:协商缓存(每次验证资源是否更新)
      location / {
        try_files $uri $uri/ /index.html; # SPA 项目路由兼容
        # 协商缓存核心响应头(强制校验,不直接缓存文件)
        add_header Cache-Control "no-cache, must-revalidate";
        # 开启 ETag(资源唯一标识,Nginx 默认开启,手动指定更稳妥)
        etag on;
        # 开启 Last-Modified(资源最后修改时间)
        if_modified_since on;
        # 禁止浏览器直接缓存 HTML,强制走协商流程
        expires -1;
      }
    }
    
  3. 关键配置说明

    • Cache-Control: public, max-age=31536000:允许 CDN / 浏览器缓存,有效期 1 年,静态资源优先使用。
    • immutable:告知浏览器缓存期内资源不会变更,无需发起协商请求,进一步优化性能。
    • no-cache:不是不缓存,而是缓存后每次请求必须和服务器验证资源新鲜度,适合 HTML 等需要实时更新的文件。
    • etag/if_modified_since:协商缓存的核心,服务器通过对比标识判断资源是否更新,未更新返回 304,节省带宽。

补充

如果使用 Apache 服务器,可通过 .htaccess 文件配置响应头,核心缓存策略与 Nginx 一致,仅语法略有差异,例如:

# 静态资源强缓存
<FilesMatch ".(js|css|png|jpg)$">
  Header set Cache-Control "public, max-age=31536000"
</FilesMatch>

# HTML 协商缓存
<FilesMatch ".html$">
  Header set Cache-Control "no-cache, must-revalidate"
</FilesMatch>

Vue2 项目首屏缓存优化具体配置代码

以下配置覆盖静态资源强缓存、HTML 协商缓存、预加载、打包优化四大核心,直接复用即可。

一、第一步:Webpack 配置(内容哈希命名,支持长期缓存)

Vue2 项目通常基于 webpack 构建(vue-cli 2/3+),核心是给打包后的静态资源加内容哈希,确保内容不变则 URL 不变,缓存长期有效。

1. vue-cli 3+(vue.config.js)

// vue.config.js
module.exports = {
  // 1. 配置打包输出文件名,添加内容哈希(chunkhash)
  configureWebpack: {
    output: {
      // 入口文件哈希
      filename: 'js/[name].[contenthash:8].js',
      // 非入口chunk(如异步组件)哈希
      chunkFilename: 'js/[name].[contenthash:8].chunk.js'
    }
  },
  // 2. 配置css打包哈希
  css: {
    extract: {
      filename: 'css/[name].[contenthash:8].css',
      chunkFilename: 'css/[name].[contenthash:8].chunk.css'
    }
  },
  // 3. 生产环境关闭sourceMap(减小文件体积,提升加载速度)
  productionSourceMap: false
}

2. vue-cli 2(build/webpack.prod.conf.js)

// build/webpack.prod.conf.js
module.exports = {
  output: {
    filename: utils.assetsPath('js/[name].[contenthash:8].js'),
    chunkFilename: utils.assetsPath('js/[name].[contenthash:8].chunk.js')
  },
  // 其他配置同vue-cli 3+,重点修改filename添加contenthash
}

二、第二步:Nginx 配置(缓存策略,强缓存 + 协商缓存)

前端打包后部署在 Nginx 上,通过 Nginx 配置 HTTP 响应头,实现静态资源强缓存、HTML 协商缓存。

# nginx.conf 或 站点配置文件
server {
  listen 80;
  server_name your-domain.com;
  root /usr/share/nginx/html; # 你的Vue打包后dist目录路径

  # 1. 静态资源(JS/CSS/图片/字体等):强缓存 1 年
  location ~* .(js|css|png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot)$ {
    # 强缓存配置,优先级最高
    add_header Cache-Control "public, max-age=31536000, immutable";
    # 兼容HTTP 1.0,配合Cache-Control
    expires 1y;
    # 开启gzip压缩,减小传输体积
    gzip on;
    # 缓存命中日志(可选,便于排查)
    access_log /var/log/nginx/cache_access.log;
  }

  # 2. 首屏 HTML:协商缓存,不直接缓存文件,每次验证新鲜度
  location / {
    try_files $uri $uri/ /index.html; # Vue SPA 路由兼容
    # 协商缓存配置:强制验证资源是否更新
    add_header Cache-Control "no-cache, must-revalidate";
    # 配置ETagNginx默认开启,可手动指定)
    etag on;
    # 配置Last-Modified
    if_modified_since on;
    expires -1; # 禁止浏览器直接缓存HTML
  }
}

配置说明:

  • immutable:告诉浏览器该资源在缓存期内不会变更,无需发起协商请求,进一步优化首屏。
  • no-cache:不是不缓存,而是缓存后每次请求都要和服务端验证(协商缓存),保证 HTML 始终是最新的。

三、第三步:Vue 项目内配置(预加载核心资源,提升首屏加载速度)

在 public/index.html 中添加 preload/preconnect,预加载首屏关键资源,减少请求延迟。

<!-- public/index.html -->
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>

    <!-- 1. 预连接CDN(如果静态资源部署在CDN,提前建立连接) -->
    <link rel="preconnect" href="https://your-cdn-domain.com">

    <!-- 2. 预加载首屏核心CSS(打包后的核心样式文件,替换为你的哈希文件名) -->
    <link rel="preload" href="/css/app.abc12345.css" as="style">

    <!-- 3. 预加载首屏核心JS(打包后的入口JS,替换为你的哈希文件名) -->
    <link rel="preload" href="/js/app.abc12345.js" as="script">

    <!-- 4. 预加载关键字体(如有首屏展示的自定义字体) -->
    <link rel="preload" href="/fonts/iconfont.woff2" as="font" type="font/woff2" crossorigin>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

说明:

  • preload 仅加载首屏必需资源,不要滥用(过多预加载会占用带宽,适得其反)。
  • 打包后的资源文件名可在 dist 目录中查看,部署时确保路径对应。

四、第四步:可选配置(Service Worker 离线缓存,二次访问极致优化)

Vue2 可通过 workbox-webpack-plugin 实现 Service Worker 缓存,二次访问首屏直接从本地缓存读取,无需网络请求。

1. 安装依赖

npm install workbox-webpack-plugin --save-dev

2. 修改 vue.config.js

// vue.config.js
const { InjectManifest } = require('workbox-webpack-plugin');

module.exports = {
  configureWebpack: {
    // 其他配置...
    plugins: [
      // 注入Service Worker配置
      new InjectManifest({
        swSrc: './src/service-worker.js', // 自定义SW文件
        swDest: 'service-worker.js', // 输出文件名
        exclude: [/.map$/, /manifest.json$/, /.htaccess$/], // 排除无需缓存的文件
      })
    ]
  },
  pwa: {
    enabled: true, // 开启PWA支持
    registerServiceWorker: true, // 自动注册SW
  }
}

3. 创建 src/service-worker.js

// src/service-worker.js
workbox.core.setCacheNameDetails({ prefix: 'vue2-app' });

// 缓存首屏核心资源(HTML/JS/CSS)
workbox.routing.registerRoute(
  ({ request }) => request.destination === 'document' || 
                   request.destination === 'script' || 
                   request.destination === 'style',
  new workbox.strategies.CacheFirst({
    cacheName: 'vue2-app-core',
    plugins: [
      new workbox.expiration.ExpirationPlugin({ maxAgeSeconds: 31536000 })
    ]
  })
);

// 缓存图片资源
workbox.routing.registerRoute(
  ({ request }) => request.destination === 'image',
  new workbox.strategies.CacheFirst({
    cacheName: 'vue2-app-images',
    plugins: [
      new workbox.expiration.ExpirationPlugin({ maxEntries: 100, maxAgeSeconds: 86400 })
    ]
  })
);

五、配置验证

  1. 打包项目:npm run build,查看 dist 目录,确认资源文件名是否带有 8 位哈希。

  2. 部署到 Nginx 后,打开浏览器开发者工具(F12)→ Network 面板,刷新页面:

    • JS/CSS 等静态资源:Status 为 200 (from disk cache) 或 200 (from memory cache),表示强缓存生效。
    • index.html:Status 为 200 或 304,表示协商缓存生效。
  3. 二次访问:首屏加载时间大幅降低(尤其是 Service Worker 配置后,离线也可访问)。

总结

  1. 核心是内容哈希 + 长期强缓存,保证静态资源不重复下载。
  2. HTML 用协商缓存,保证首屏内容最新。
  3. preload 预加载关键资源,进一步缩短首屏等待时间。
  4. Service Worker 针对二次访问优化,实现离线可用。

如果部署后出现缓存不生效、资源 404 等问题,可优先检查 Nginx 路径配置和资源哈希文件名是否对应。