HTTP 与浏览器全过程

共 20 题
📑 题目列表 20 题
#
★★★

1. 从浏览器输入 URL 到页面展示的完整过程,DNS、TCP/TLS、HTTP、渲染各阶段的关键细节如何?

请描述从浏览器输入 URL 到页面展示的完整过程,并说明 DNS、TCP/TLS、HTTP、渲染各阶段的关键细节?

  • 输入 URL 后的完整请求链路(DNS、TCP、TLS、HTTP 请求、响应、渲染)
  • 各阶段的关键细节(缓存、TCP 四次握手、TLS 握手、连接复用)
  • 渲染管线与关键渲染路径

整个过程可分为若干阶段:首先浏览器解析输入 URL(判断是合法域名还是搜索词),进行 HTTP 缓存查询(强缓存命中则直接使用本地缓存,不再发起网络请求);然后进行 DNS 解析,依次查询本地 DNS 缓存、系统 hosts 文件、本地 DNS 服务器,最终得到目标 IP,期间可能经过递归查询与多级缓存;随后建立 TCP 连接(若 Keep-Alive 或 HTTP/2 连接池已有连接则复用,否则三次握手),若为 HTTPS 还需进行 TLS 握手(TLS 1.3 为 1-RTT,重连可 0-RTT),协商加密参数并校验证书;接着通过 HTTP 发送请求(若使用 HTTP/2 则在单一连接上多路复用多个流),服务端处理并返回响应(含状态码、响应头、响应体),浏览器判定缓存策略(Cache-Control/ETag)决定是否缓存;最后浏览器进行渲染:解析 HTML 构建 DOM 树、解析 CSS 构建 CSSOM、合并为渲染树、进行布局(Layout)、绘制(Paint)与合成(Composite),在构建过程中同步解析并加载 script/img/link 等资源,JavaScript 会阻塞 DOM 解析(除非 async/defer),CSS 会阻塞渲染。

该题考察对完整网络链路与浏览器工作原理的整体把握。回答重点是"按阶段推进",并突出各阶段的关键细节(缓存、连接复用、TLS 握手、渲染阻塞),体现对性能优化入口(DNS 预解析、HTTP/2、缓存、关键渲染路径)的理解。

#
★★★

2. HTTP 常见状态码语义辨析,301/302/304、401/403、502/503/504 的准确区别与排查指向如何?

请辨析 HTTP 常见状态码 301/302/304、401/403、502/503/504 的准确区别,并说明各自的排查指向?

  • 301/302/304 的重定向与缓存语义
  • 401/403 的认证与授权区别
  • 502/503/504 的网关与服务器错误区别

301(Moved Permanently)为永久重定向,浏览器会缓存该重定向并更新书签,后续请求直接访问新地址;302(Found)为临时重定向,不缓存,每次请求都需重新访问当前地址;304(Not Modified)为协商缓存命中,服务端告知客户端"资源未变",客户端可使用本地缓存,本质是"无响应体"的重定向/缓存类响应。401(Unauthorized)表示未认证,需要提供身份凭证(如登录),通常配合 WWW-Authenticate 头;403(Forbidden)表示服务器理解请求但拒绝访问,通常是权限不足(已认证但无授权),排查时需关注权限配置而非认证。502(Bad Gateway)表示网关或代理收到上游服务器的无效响应(上游宕机、连接失败、应用崩溃);503(Service Unavailable)表示服务器暂时无法处理(过载、维护中),通常可配合 Retry-After 头;504(Gateway Timeout)表示网关在等待上游响应时超时。排查指向:301/302 检查重定向配置与 URL 变更,304 检查缓存协商,401/403 检查认证授权体系,502/504 检查上游应用与网关,503 检查服务负载与限流。

状态码分三大类辨清:3xx 是"重定向与缓存",401/403 是"认证与授权"的区别,5xx 是"服务器/网关侧错误"。502/503/504 的区别尤其关键:502 是上游"坏响应",503 是"自身不可用",504 是"上游超时"。

#
★★★

3. GET 与 POST 的本质区别,幂等性、缓存、编码与"长度限制"的真相如何?

请说明 GET 与 POST 的本质区别,重点辨析幂等性、缓存、编码方式与"URL 长度限制"的真相?

  • 语义差异(安全/幂等性)而非传输方式差异
  • 缓存与书签行为差异
  • URL 长度限制的真相(是客户端/服务器限制而非协议限制)

GET 与 POST 的本质区别在于语义:GET 用于获取资源,是"安全"(不改变服务器状态)且"幂等"(重复执行结果相同)的方法,可被缓存、可被书签收藏、可被预取;POST 用于提交数据、执行操作,不保证安全也不幂等,通常不可缓存、不可被书签收藏。从传输层面看,两者都可用 body 携带数据,但 GET 的习惯是把数据放在 URL 查询串中,POST 通常放请求体(body)。关于"URL 长度限制":这不是 HTTP 协议的限制,而是浏览器实现限制各不相同(如 IE 约 2083 字符、Chrome 约 2MB),服务器如 nginx 默认 large_client_header_buffers 约 8KB 的配置限制,POST 报文长度同样受服务器配置限制;因此"GET 有长度限制、POST 无限制"是误解。编码差异:GET 由于数据在 URL 中,需进行 URL 编码;POST 的 body 可通过 Content-Type 指定格式(application/x-www-form-urlencoded、multipart/form-data、application/json 等)。GET 与 POST 的幂等性差异影响缓存与重试:GET 可安全重试与缓存,POST 重试可能产生重复副作用,需在应用层做幂等处理。

该题的核心是"语义与行为差异"而非"传输方式差异"。GET 的安全幂等与 POST 的非幂等,决定了缓存、书签、重试等行为差异;"URL 长度限制"是客户端/服务器实现限制而非协议规定,是常见误区。

#
★★★

4. 从输入 URL 到页面渲染的完整过程,每一步的缓存与优化机会在哪里?

请描述从输入 URL 到页面渲染的完整过程,并分析每一步的缓存与优化机会?

  • 完整请求链路的缓存层次(DNS、HTTP、浏览器)
  • 各阶段的优化机会(DNS 预解析、连接复用、缓存、关键渲染路径)
  • 前端性能优化与后端性能优化的配合

完整过程:URL 解析 → DNS 解析 → TCP 连接 → TLS 握手(HTTPS)→ 发送 HTTP 请求 → 服务端处理 → 返回响应 → 浏览器解析渲染。每一步的缓存与优化机会:DNS 阶段可通过 DNS 预解析(dns-prefetch)、加大 DNS 缓存 TTL、减少跨域域名数量来降低解析时延;TCP/TLS 阶段可通过 HTTP/2 连接复用、TLS 会话复用(session resumption/0-RTT)、启用 TLS 1.3 减少握手往返;HTTP 阶段可通过强缓存(Cache-Control)与协商缓存(ETag/Last-Modified)减少重复请求,通过 CDN 就近分发、压缩传输(gzip/br)、HTTP/2 多路复用减少传输体积与往返;服务端阶段通过数据库缓存、页面缓存、边缘计算(Edge)降低处理时延;渲染阶段通过关键渲染路径优化——减少渲染阻塞资源(CSS/JS 的 defer/async)、内联关键 CSS、剥离非关键资源、懒加载图片、减少 DOM 深度,来缩短首屏时间。缓存与优化贯穿全链路,是"从用户输入到像素展示"的每毫秒取舍。

该题强调"全链路优化思维"。回答需按阶段列出缓存层次与优化手段,体现对 DNS、传输、HTTP、渲染各层优化入口的全面理解,这比单独讲某一层更能体现工程能力。

#
★★★

5. CORS 预检(preflight)机制,哪些请求会触发 OPTIONS 预检,简单请求与预检请求的判定条件如何?

请解释 CORS 预检(preflight)机制,说明哪些请求会触发 OPTIONS 预检,以及简单请求与预检请求的判定条件?

  • CORS 跨域资源共享的基本原理
  • 简单请求的判定条件(方法、头、Content-Type)
  • 预检请求(OPTIONS)触发条件与 Preflight 缓存

CORS(Cross-Origin Resource Sharing)是浏览器用于跨域资源共享的机制,隔离了跨域请求的限制。浏览器将请求分为简单请求与预检请求:简单请求需同时满足三个条件——方法为 GET/HEAD/POST,自定义头仅允许 Accept、Accept-Language、Content-Language、Content-Type(Content-Type 仅限 application/x-www-form-urlencoded、multipart/form-data、text/plain),且不使用 ReadableStream 等;简单请求可直接发送,浏览器在响应头中检查 Access-Control-Allow-Origin 等来判定是否放行。非简单请求(如带自定义头、使用 PUT/DELETE、Content-Type 为 application/json、携带 cookie 凭据等)会先触发预检:浏览器先发送一个 OPTIONS 预检请求,携带 Access-Control-Request-Method 与 Access-Control-Request-Headers,询问服务器是否允许该跨域请求;服务器通过 Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Allow-Origin 等响应头告知允许范围,浏览器确认后才发送实际请求。预检结果可通过 Access-Control-Max-Age 缓存,减少重复预检。预检是浏览器安全机制的一部分,防止不可信跨域请求在未获授权前执行有副作用的操作。

CORS 预检的核心是"先询问后执行"以保护非简单请求。判定简单请求的三要素(方法、头、Content-Type)与预检触发条件(自定义头、非简单方法、非简单 Content-Type)是回答重点,也是排查跨域问题的关键。

#
★★★

6. 浏览器同源策略的边界,同源的定义,哪些资源加载不受同源限制(img/script/link),与 CORS 的配合关系如何?

请解释浏览器同源策略的定义与边界,说明哪些资源加载不受同源限制,以及同源策略与 CORS 的配合关系?

  • 同源的定义(协议、域名、端口)
  • 不受同源限制的资源加载(img/script/link)
  • 同源策略与 CORS 的配合

同源策略是浏览器安全的基础,规定只有在"协议、域名、端口"三者都相同(同源)时,页面才能访问另一页面的资源与数据。同源策略限制 JavaScript 跨域读取数据(如 XHR/fetch 默认受限、跨域读取 Cookie/LocalStorage 受限),但某些资源加载不受同源限制:img 标签可加载任意域名的图片,script 标签可加载任意域名的脚本(但脚本执行后的数据访问仍受同源限制),link 可加载任意域名的 CSS/字体等,form 可提交到任意域名。这些"可加载但不可读"的资源正是 JSONP 与 CDN 分发的基础。同源策略与 CORS 是"限制"与"放行"的配合:默认同源策略阻止跨域读取,CORS 通过服务器返回的 Access-Control-Allow-Origin 等头,明确声明"允许哪些源访问",从而在可控前提下放行跨域请求。CORS 是服务端授权机制,同源策略是浏览器默认约束,两者配合实现了"默认收紧、显式放行"的安全模型。

同源策略的关键是"可加载不等于可读取":img/script/link 能加载跨域资源,但脚本无法读取跨域数据,这是安全边界。CORS 是"显式授权"放行机制,二者配合构成浏览器的安全模型。

#
★★

7. HTTP/1.1、HTTP/2、HTTP/3 的演进主线,队头阻塞在每一代如何被部分解决?

请描述 HTTP/1.1、HTTP/2、HTTP/3 的演进主线,重点说明队头阻塞在每一代如何被部分解决?

  • HTTP/1.1 的队头阻塞(管道与连接复用)
  • HTTP/2 的多路复用与二进制分帧
  • HTTP/3 基于 QUIC 消除 TCP 层队头阻塞

HTTP/1.1 存在队头阻塞:同一连接上请求必须串行处理(虽然引入了 Keep-Alive 连接复用与管道,但管道仍要求响应有序返回,且多数浏览器未启用),导致一个慢请求阻塞后续请求,只能通过多开连接(浏览器约 6 个)缓解。HTTP/2 通过二进制分帧层实现多路复用(Multiplexing):将多个请求/响应流拆分为帧,在单一 TCP 连接上交错传输,解决了 HTTP 层(应用层)的队头阻塞;但 HTTP/2 仍基于 TCP,当某个 TCP 包丢失时,TCP 的按序交付会阻塞整个连接的所有流,即仍存在 TCP 层队头阻塞。HTTP/3 基于 QUIC(UDP 之上实现),将每个流独立管理,每个流有独立的序号与重传,一个流丢包不影响其他流,从根本上消除了 TCP 层队头阻塞,同时引入 0-RTT 与连接迁移等能力。演进主线是:HTTP/1.1 串行 → HTTP/2 应用层多路复用(解决 HTTP 层队头阻塞)→ HTTP/3 传输层流隔离(解决 TCP 层队头阻塞)。

队头阻塞分两层:HTTP/1.1 的"请求串行"与 HTTP/2 仍存在的"TCP 层队头阻塞"。HTTP/2 解决前者,HTTP/3 的流隔离解决后者,这是演进主线,也是回答该题的关键脉络。

#
★★

8. Cookie、Session、Token(JWT)三种会话保持机制的对比?

请对比 Cookie、Session、Token(JWT)三种会话保持机制的原理、优缺点与适用场景?

  • Cookie 的客户端存储与会话保持
  • Session 的服务端存储与状态
  • Token(JWT)的无状态自包含特性

Cookie 是浏览器存储的小型数据,由服务器通过 Set-Cookie 下发,浏览器在后续请求中自动携带,用于会话保持;但 Cookie 存于客户端,有大小限制(约 4KB),且存在被窃取(XSS)风险,可通过 HttpOnly、Secure、SameSite 加强。Session 是服务端存储的会话状态,服务器维护会话数据(内存或 Redis),给客户端一个 SessionID(通常存于 Cookie),客户端携带 SessionID 即可;Session 集中式存储便于服务端控制与注销,但存在状态存储压力,多服务器需共享存储(如 Redis),且天然有 Cookie 的局限。Token(JWT)是无状态、自包含的令牌:如 JWT 由 Header、Payload、Signature 构成,服务器用密钥签名,客户端持有后在请求头(Authorization: Bearer)中携带,服务器验签即可识别用户,无需服务端存储会话;JWT 无状态、跨域支持好、适合分布式/微服务,但无法主动撤销(除非加黑名单)、Payload 有安全风险(需合理设置过期时间)、体积较大。三者适用场景:需要简单服务端控制的用 Session,需要跨域/无状态/分布式认证的用 Token(JWT),Cookie 作为前两者的载体。

Cookie 是"载体",Session 是"服务端状态",Token/JWT 是"无状态自包含凭据"。三者对比核心是"状态存哪"(客户端 vs 服务端)与"能否主动撤销"(Session 可、JWT 难),这决定了各自适用场景。

#
★★

9. HTTP 缓存协商(ETag/Last-Modified)与启发式缓存的工作机制?

请解释 HTTP 缓存协商(ETag/Last-Modified)与启发式缓存的工作机制?

  • 强缓存与协商缓存的区别
  • ETag 与 Last-Modified 的验证机制
  • 启发式缓存的工作原理

HTTP 缓存分为强缓存与协商缓存(弱缓存)。强缓存通过 Cache-Control(max-age/s-maxage)或 Expires 指定缓存有效期,有效期内浏览器直接使用本地缓存,不发请求。协商缓存是当强缓存过期或未命中时,浏览器携带条件请求头向服务器验证资源是否变化:一种是 Last-Modified/If-Modified-Since,服务器用文件最后修改时间判断,若未变返回 304,否则返回 200 与最新内容;另一种是 ETag/If-None-Match,ETag 是资源内容的指纹(如哈希),更精确,能处理"时间相同但内容变化"以及"秒级时间戳精度不足"的问题,优先级高于 Last-Modified。启发式缓存:当响应没有明确的缓存控制头(无 Cache-Control/Expires)时,浏览器依据启发式算法估算缓存时间(如基于 Last-Modified 与实际时间差值的 10% 作为缓存有效期),这是浏览器后端的默认行为,可能造成缓存不可控,因此生产环境应显式设置缓存头。

强缓存与协商缓存是"先用本地"与"先验证"的关系。ETag 比 Last-Modified 更精确(内容指纹),启发式缓存是"无明确缓存头时的兜底",理解其不可控性才能正确设置缓存策略。

#
★★

10. 浏览器的渲染管线,DOM/CSSOM/布局/绘制/合成如何衔接?

请描述浏览器的渲染管线,说明 DOM、CSSOM、布局、绘制、合成各阶段的作用?

  • DOM 与 CSSOM 树的构建
  • 渲染树、布局(Layout)、绘制(Paint)与合成(Composite)
  • 关键渲染路径与重排/重绘

浏览器渲染管线分为几个阶段:首先解析 HTML 构建 DOM 树、解析 CSS 构建 CSSOM 树,两者是渲染的基础(DOM 是文档结构,CSSOM 是样式规则);随后结合 DOM 与 CSSOM 构建渲染树(Render Tree),只包含可见元素并计算样式;接着进行布局(Layout/Reflow),计算每个可见元素的几何位置与尺寸;然后进行绘制(Paint),将元素绘制到图层(layer)上;最后进行合成(Composite),将各图层按顺序合成到屏幕上,GPU 参与合成可提升性能。关键渲染路径即"构建 DOM/CSSOM → 渲染树 → 布局 → 绘制 → 合成"。当修改样式或布局属性时,会触发重排(Reflow,重新布局)或重绘(Repaint);重排比重绘代价高,频繁操作 DOM 或读取布局属性会强制同步布局,降低性能。优化手段包括:批量修改样式、使用 transform/opacity 触发合成(不触发重排)、避免强制同步布局、减少 DOM 深度等。

渲染管线是浏览器性能优化的理论基础。重点是理解各阶段顺序与触发条件(重排 vs 重绘 vs 合成),以及 transform/opacity 走合成层的高效性,这是前端性能优化的核心。

#
★★

11. HTTP 分块传输编码(chunked)与 Content-Length,流式响应时为什么不能使用 Content-Length?

请解释 HTTP 分块传输编码(chunked)与 Content-Length 的关系,说明流式响应时为什么不能使用 Content-Length?

  • Content-Length 与 chunked 的边界作用
  • 动态/流式响应无法预知长度
  • chunked 的格式(块大小 + 数据 + 终止块)

HTTP 响应中,Content-Length 头用于告知响应体长度,接收方据此知道"何时读完整响应",保证消息边界。但对于动态生成、流式输出的响应,服务器在发送开始时往往不知道总长度,因此无法设置 Content-Length。此时使用分块传输编码(Transfer-Encoding: chunked):服务器将响应体拆成多个块,每块以"十六进制长度 + \r\n + 数据 + \r\n"的格式发送,最后以"0\r\n\r\n"(长度为 0 的块)表示结束,接收方根据块长度解析,直到读到终止块。分块传输的好处是无需预知总长度,可边生成边发送(如流式日志、大文件下载、SSE、长轮询),且支持流式压缩。chunked 与 Content-Length 互斥:一个响应只能使用其中一种方式界定边界,若同时使用以 Transfer-Encoding: chunked 为准。HTTP/1.1 中,Keep-Alive 连接复用依赖明确的边界(Content-Length 或 chunked),否则接收方无法判断响应何时结束。

chunked 解决"动态内容长度未知"的边界问题。核心是"消息边界"与"长度预知"的权衡:能预知用 Content-Length,不能预知用 chunked。这也解释了为什么流式响应无法使用 Content-Length。

#
★★

12. HTTP 方法的安全性与幂等性,GET/HEAD/OPTIONS 安全、PUT/DELETE 幂等而 POST 不幂等,对缓存与重试的影响如何?

请解释 HTTP 方法的安全性与幂等性,说明 GET/HEAD/OPTIONS 安全、PUT/DELETE 幂等而 POST 不幂等的原因,以及对缓存与重试的影响?

  • 安全方法(不改变资源状态)与幂等方法(重复执行结果相同)
  • 各方法的安全性与幂等性分类
  • 对缓存与重试的影响

HTTP 方法的安全性(safe)指方法不会改变服务器资源状态,可安全缓存与预取;幂等性(idempotent)指重复执行该方法与执行一次结果相同(对服务器状态的影响一致)。分类:GET 安全且幂等;HEAD 安全且幂等(只返回响应头,无响应体);OPTIONS 安全且幂等(用于探测服务器支持的方法);PUT 非安全但幂等(重复 PUT 同一资源结果一致);DELETE 非安全但幂等(重复删除结果一致,即使资源已不存在,状态不变);POST 非安全也不幂等(每次提交可能产生新资源或副作用,如创建订单);PATCH 通常非幂等。对缓存与重试的影响:安全方法(GET/HEAD/OPTIONS)可被代理与浏览器缓存、可预取、可安全重试;幂等方法(PUT/DELETE)在网络超时后可安全重试(结果一致),而 POST 因不幂等,重试可能导致重复副作用(重复下单、重复写入),因此客户端对 POST 需谨慎重试,或在应用层设计幂等(如幂等键)。理解安全性与幂等性对设计 REST API、缓存策略与重试机制至关重要。

安全性与幂等性是 HTTP 语义的两大属性。安全性决定"能否缓存",幂等性决定"能否安全重试"。POST 不幂等是重试风险与幂等设计(幂等键)的根源,是工程实践的关键。

#
★★

13. DNS 解析的缓存层级与 TTL 对故障恢复的影响?

请解释 DNS 解析的缓存层级,并分析 TTL 对故障恢复的影响?

  • DNS 的缓存层级(本地、递归、权威)
  • TTL 的作用与配置
  • DNS 故障切换的时延与 TTL 的关系

DNS 解析存在多级缓存:浏览器缓存、操作系统(hosts 与系统缓存)缓存、本地 DNS 服务器(递归解析器)缓存、根/顶级/权威服务器。每一级都按记录的 TTL(Time To Live,生存时间)缓存解析结果。TTL 决定了 DNS 记录在缓存中的存活时间,影响解析的时效与负载:TTL 过短会导致频繁回源查询、增大权威服务器负载;TTL 过长会延迟记录变更生效。对故障恢复的影响:当服务 IP 变更(如故障切换、CDN 切换)时,由于各缓存层仍按旧 TTL 缓存旧 IP,即使权威服务器已更新,客户端仍会继续访问旧 IP,直到 TTL 到期重新查询。因此,故障切换的"生效时间"约等于各缓存层 TTL 之和,TTL 越大,故障/切换后的收敛越慢。工程上,DNS 切换前会预先调低 TTL(如从 3600 降到 60),等缓存刷新后再切换,以加速收敛;同时需考虑运营商的强制缓存(忽略 TTL)与本地 hosts 的影响。合理设置 TTL 是平衡"解析性能"与"故障收敛速度"的关键。

DNS 缓存层级与 TTL 是网络故障收敛的核心。TTL 决定"变更传播的上限时延",故障切换需考虑"先降 TTL 预热再切换"的策略,这是运维与故障恢复的实践要点。

#
★★

14. Cookie 与 Session,SameSite、HttpOnly 与跨域携带如何处理?

请解释 Cookie 与 Session 的配合机制,说明 SameSite、HttpOnly 属性与跨域携带 Cookie 的问题?

  • Cookie 属性(HttpOnly、Secure、SameSite)
  • Cookie 的跨域携带与 CORS 凭据
  • 安全加固(XSS 防护与 CSRF 防护)

Cookie 通常作为 Session 的载体:服务器生成 SessionID 存放在 Cookie 中下发,浏览器自动携带,服务器据此识别会话。Cookie 的关键属性:HttpOnly 使 Cookie 无法被 JavaScript 读取(document.cookie),防止 XSS 窃取会话;Secure 使 Cookie 仅在 HTTPS 下传输;SameSite 控制 Cookie 的跨站发送行为,取值 Strict(完全禁止跨站携带)、Lax(允许顶级导航的 GET 携带)、None(允许跨站携带,需同时设置 Secure)。跨域携带 Cookie 涉及 CORS 与凭据:跨域请求若要携带 Cookie,前端需设置 credentials: 'include',服务器需返回 Access-Control-Allow-Credentials: true 且 Access-Control-Allow-Origin 不能为通配符 *。SameSite 主要用于防御 CSRF:攻击者利用浏览器自动携带 Cookie 的特性,诱导用户发起跨站请求执行操作;SameSite=Lax/Strict 限制跨站请求携带 Cookie,从而降低 CSRF 风险。综合使用 HttpOnly(防 XSS 窃取)、SameSite(防 CSRF)、Secure(防明文窃听)、短有效期,是 Cookie 安全加固的标准做法。

Cookie 属性是网络安全实践的基础。HttpOnly 防 XSS 窃取、SameSite 防 CSRF、Secure 防窃听,三者针对不同攻击面;跨域携带还需 CORS 凭据配合,是前端联调常见的坑。

#
★★

15. HTTPS 握手与证书,TLS 1.3 的简化握手如何工作?

请解释 HTTPS 握手与证书验证流程,重点说明 TLS 1.3 的简化握手?

  • TLS 握手的密钥协商过程
  • TLS 1.3 的 1-RTT 简化握手与 0-RTT
  • 证书验证与安全性

HTTPS 依赖 TLS 在 TCP 之上提供加密与完整性。TLS 1.2 握手需要 2-RTT:客户端发送 ClientHello(含支持的加密套件、随机数),服务器回复 ServerHello、证书、密钥交换参数,双方交换并生成会话密钥,最后发送 Finished 确认。TLS 1.3 简化为 1-RTT:客户端在 ClientHello 中直接携带其支持的密钥共享(key_share,基于椭圆曲线 Diffie-Hellman),服务器选择参数后直接在 ServerHello 中回复密钥共享,双方即可各自计算出会话密钥,省去一次往返,显著降低握手延迟;同时 TLS 1.3 移除了不安全的加密套件(如 RSA 密钥交换、CBC 模式),只保留前向保密(PFS)的套件。TLS 1.3 还支持 0-RTT:对已建立过连接的客户端,若缓存了会话票据(PSK),可在首个 ClientHello 中直接携带应用数据,实现"零往返"建立连接,但 0-RTT 存在重放攻击风险,只能用于幂等请求。证书验证流程:客户端校验证书链(服务器证书 → 中间证书 → 根证书),检查颁发者、有效期、域名(SAN)、吊销状态(CRL/OCSP),确认证书可信后才继续握手。TLS 1.3 的简化握手通过"密钥共享提前携带"减少往返,是降低 HTTPS 延迟的关键优化。

TLS 1.3 的核心改进是"密钥协商提前化"(ClientHello 携带 key_share → 1-RTT)与"0-RTT 复用"。理解握手的往返次数演进(TLS 1.2 的 2-RTT → TLS 1.3 的 1-RTT → 0-RTT)是回答重点。

#
★★

16. HTTP Keep-Alive 与连接复用,Keep-Alive 超时与最大请求数限制,连接池在浏览器与服务器的不同实现如何?

请解释 HTTP Keep-Alive 与连接复用机制,说明 Keep-Alive 超时与最大请求数限制,以及连接池在浏览器与服务器的不同实现?

  • Keep-Alive 长连接与连接复用
  • Keep-Alive 超时与最大请求数限制
  • 浏览器与服务器的连接池差异

HTTP Keep-Alive 允许在一次 TCP 连接上复用多个请求/响应,避免每次请求都重建连接,从而节省三次握手与慢启动的开销。HTTP/1.1 默认开启 Keep-Alive。服务器会为每个空闲连接设置 Keep-Alive 超时(如 nginx 的 keepalive_timeout,默认约 75 秒)与最大请求数限制(如 nginx 的 keepalive_requests),当空闲超时或请求数达到上限时,服务器关闭连接,防止空闲连接耗尽资源。连接池实现:浏览器端,每个域名维护一个连接池(通常最多约 6 个连接,HTTP/2 则单连接多路复用),请求按域名复用连接,连接空闲超时后回收;服务器端,连接池/keepalive 配置决定能保持的空闲连接数量与超时,配合事件驱动(如 epoll)高效管理大量长连接。两者差异:浏览器连接池规模小、面向单用户、以复用为主;服务器连接池面向海量并发连接,需权衡空闲连接的资源占用(fd、内存)与复用收益,通过超时与最大请求数控制连接生命周期。Keep-Alive 超时与连接数限制是服务器资源管理的关键参数,过短降低复用收益,过长浪费资源。

Keep-Alive 的本质是"以空间换时间"的复用策略。浏览器与服务器连接池的目标不同(前者复用、后者管理海量连接),超时与最大请求数是平衡复用收益与资源占用的一对关键参数。

#
★★

17. HTTP 内容协商,Accept/Accept-Language/Accept-Encoding 如何参与协商,Vary 头对缓存有何影响?

请解释 HTTP 内容协商机制,说明 Accept/Accept-Language/Accept-Encoding 如何参与协商,以及 Vary 头对缓存的影响?

  • 内容协商的请求头与响应头
  • Accept 系列头的协商逻辑
  • Vary 头对缓存命中与区分的影响

HTTP 内容协商是指客户端与服务器协商出最合适的响应内容(媒体类型、语言、编码等)。客户端通过请求头声明偏好:Accept 声明可接受的媒体类型(如 text/html、application/json)及优先级(q 值);Accept-Language 声明可接受的语言(如 zh-CN, zh;q=0.9, en;q=0.8);Accept-Encoding 声明可接受的压缩编码(如 gzip、br、deflate);服务器据此选择最合适的表示返回。服务器响应时通过 Content-Type、Content-Language、Content-Encoding 告知实际返回的内容。Vary 头的影响:当缓存同时存在"同一 URL 的不同表示"时,缓存需要知道响应取决于哪些请求头,才能正确区分。Vary 头(如 Vary: Accept-Encoding)声明响应随这些请求头变化,缓存需按"URL + 这些请求头"作为缓存键,否则会错误地把一种表示(如 gzip 版)返回给需要另一种(如 br 版)的客户端,导致内容错乱。因此 Vary 头是内容协商与缓存正确配合的关键,影响缓存命中率与缓存正确性。

内容协商是"客户端声明偏好、服务器选择表示"的过程。Vary 头的作用是告诉缓存"响应取决于哪些请求头",从而正确区分缓存键,避免内容协商与缓存冲突。

#
★★

18. HTTPS 证书链验证流程,客户端如何校验证书链、吊销状态(CRL/OCSP)与中间人攻击的关系如何?

请解释 HTTPS 证书链验证流程,说明客户端如何校验证书链、吊销状态(CRL/OCSP),以及这些机制与中间人攻击的关系?

  • 证书链结构(根证书、中间证书、服务器证书)
  • 证书链验证(颁发者、有效期、域名、签名)
  • 吊销状态(CRL/OCSP)与中间人攻击

HTTPS 证书链验证流程:客户端收到服务器证书后,首先校验其可信。证书链由受信任的根证书(预装在系统/浏览器信任库)、中间证书、服务器证书组成。客户端验证步骤:确认服务器证书的域名(SAN)与访问域名匹配;校验证书有效期;沿证书链向上,用上级证书的公钥验证下级证书的签名,直到找到信任库中的根证书,确认整条链可信;检查证书吊销状态——通过 CRL(证书吊销列表,黑名单式)或 OCSP(在线证书状态协议,实时查询)确认证书是否被吊销。吊销机制的作用:证书私钥泄露或证书被滥用时,CA 可吊销证书,客户端通过 CRL/OCSP 即时获知,避免继续信任已失效证书。与中间人攻击的关系:中间人攻击(MITM)是指在客户端与服务器之间冒充服务器,伪造证书。若客户端证书验证不严格(如忽略域名校验、不验证吊销、信任私有根证书、忽略证书错误),攻击者即可用自签或伪造证书完成中间人劫持,窃听或篡改流量。因此严格的证书链验证(含域名、有效期、签名、吊销检查)是防御中间人攻击的关键;OCSP 相比 CRL 更实时,但存在隐私泄露(暴露访问站点)与可用性风险,可结合 OCSP Stapling 缓解。

证书链验证是"信任链"的传递:从根证书到服务器证书逐级验签。吊销状态(CRL/OCSP)补全了"证书仍在有效期内但已被吊销"的缺口,严格的完整验证是防中间人攻击的基石。

#
★★

19. HTTP/2 与 HTTP/3 在连接复用与流控上的工程差异,连接迁移(connection migration)如何解决移动网络切换?

请解释 HTTP/2 与 HTTP/3 在连接复用与流控上的工程差异,重点说明连接迁移(connection migration)如何解决移动网络切换?

  • HTTP/2(TCP 多路复用)与 HTTP/3(QUIC 流隔离)的复用差异
  • 流控机制差异(TCP 窗口 vs QUIC 流级流控)
  • 连接迁移在移动网络切换中的作用

HTTP/2 在单个 TCP 连接上多路复用多个流,但所有流共享一个 TCP 连接,受 TCP 层队头阻塞影响(一个包丢失阻塞所有流);流控基于 TCP 的连接级窗口(rwnd/cwnd)。HTTP/3 基于 QUIC,每个流独立管理、独立序号与重传,一个流丢包不影响其他流,流控在流级(Stream-level flow control)与连接级(connection-level)两个层面实现,更精细。连接迁移(connection migration)是 QUIC 的核心特性:TCP 连接绑定四元组(源 IP、源端口、目的 IP、目的端口),当移动设备切换网络(如 Wi-Fi ↔ 4G/5G)导致 IP 变化时,TCP 连接会中断,必须重建。QUIC 使用连接 ID(Connection ID)标识连接,而非绑定 IP/端口,因此当客户端 IP 变化时,可通过新的 IP 继续使用同一连接 ID 维持连接,无需重新握手,实现无缝连接迁移。这解决了移动网络切换场景下的连接中断问题,降低重连延迟与握手开销。HTTP/2 无法实现连接迁移,切换网络需重建 TCP 连接并重新握手。

HTTP/2 与 HTTP/3 的差异本质是"基于 TCP 的流共享"与"基于 QUIC 的流隔离"之差。连接迁移(Connection ID 标识连接)是 QUIC 针对移动网络场景的关键能力,解决了 TCP 因 IP 变化而中断的问题。

#

20. 浏览器缓存机制,强缓存(Cache-Control)与协商缓存(ETag)如何配合?

请解释浏览器缓存机制,说明强缓存(Cache-Control)与协商缓存(ETag)的工作原理与区别?

  • 强缓存(Cache-Control/Expires)与协商缓存(ETag/Last-Modified)
  • 两者的触发时机与优先级
  • 缓存策略的工程实践

浏览器缓存分为强缓存与协商缓存。强缓存:通过 Cache-Control(如 max-age=3600、immutable)或 Expires 指定,浏览器在缓存有效期内直接使用本地缓存,不发网络请求,性能最高;Cache-Control 优先级高于 Expires,且支持 no-cache(需协商)、no-store(不缓存)、private/public 等指令。协商缓存:当强缓存失效或使用 no-cache 时,浏览器携带条件请求头(If-None-Match/If-Modified-Since)向服务器验证资源是否变化,服务器基于 ETag(内容指纹)或 Last-Modified(修改时间)判断,未变则返回 304(无响应体,浏览器用本地缓存),变了则返回 200 与最新内容。两者区别:强缓存"零请求"(命中直接用本地),协商缓存"至少一次请求"(需验证);强缓存优先级高于协商缓存,先查强缓存,未命中再协商。工程实践:静态资源(如 JS/CSS/图片)通常设置较长的 Cache-Control(如 max-age=31536000 + immutable),配合文件名哈希(content hash)实现更新时 URL 变化以突破缓存;HTML 等易变资源常设置 no-cache 走协商缓存。合理组合强缓存与协商缓存,可显著减少网络请求、提升加载速度。

强缓存与协商缓存是浏览器缓存的两种机制:强缓存"不请求直接用",协商缓存"请求验证后用"。理解优先级(先强后协商)、触发条件与工程实践(静态资源哈希 + 长缓存)是重点。