Skip to content
On This Page

面试题[HTTP]

1. HTTP 基础

1.1 什么是 HTTP

HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最广泛的一种网络协议,它定义了客户端(如浏览器)和服务器之间如何通信,用于传输网页、图片、视频等超文本数据。

  1. 核心特点
    • 请求-响应模型:客户端发送一个请求,服务器返回对应的响应。
    • 无状态:每个请求独立,服务器不会记住之前的请求(但可通过Cookie、Session等方式模拟状态)。
    • 基于TCP:默认使用80端口(HTTPS使用443端口)。
    • 明文传输(HTTP本身不加密,安全版本HTTPS则加密)。
  2. 发展历史
    • HTTP/1.0:简单,每个请求建立新连接
    • HTTP/1.1:引入持久连接、管道化
    • HTTP/2:多路复用、头部压缩、服务器推送
    • HTTP/3:基于QUIC(UDP),减少延迟
  3. HTTP方法
  4. HTTP状态码

1.2 HTTP 各版本的区别

按时间顺序对比主要版本的核心区别:

  1. HTTP/0.9(1991年)—— 最简单的原型
    • 只有 GET 方法,且响应只能是 HTML 文本。
    • 无状态、无头部,服务器响应后立即关闭连接。
    • 没有状态码(只有实际内容),没有版本号标识。
  2. HTTP/1.0(1996年)—— 扩展能力
    • 引入 请求方法(POST、HEAD)、状态码(200、404等)、头部字段(Content-Type、User-Agent等)。
    • 支持 缓存控制(Expires、If-Modified-Since)。
    • 缺点:每次请求建立一次 TCP 连接,连接无法复用,效率低(队头阻塞、握手开销大)。
  3. HTTP/1.1(1997年)—— 标准化的主力版本
    • 持久连接(Connection: keep-alive):默认复用同一 TCP 连接处理多个请求/响应,减少握手延迟。
    • 管道化(pipelining):允许客户端在收到前一个响应前连续发送多个请求,但服务器仍须按顺序响应,队头阻塞未完全解决。
    • 分块传输编码(chunked transfer):动态生成内容时可分块发送。
    • 新增更多方法:PUT、PATCH、DELETE、OPTIONS、TRACE、CONNECT。
    • Host 头部:支持同一 IP 上托管多个域名(虚拟主机)。
    • 更好的缓存机制(Cache-Control、ETag)。
  4. HTTP/2(2015年)—— 性能革命
    • 二进制分帧层:将 HTTP 消息拆分为更小的帧(HEADERS、DATA等),不再是文本协议。
    • 多路复用(Multiplexing):在一个 TCP 连接上交错发送多个请求/响应的帧,彻底解决 HTTP/1.x 的队头阻塞。
    • 头部压缩(HPACK):减少重复头部开销。
    • 服务器推送(Server Push):服务器可主动向客户端推送资源(如 HTML 中的 CSS/JS)。
    • 流优先级:客户端可指定请求的优先级。
    • 要求加密(虽未强制,但主流浏览器仅支持基于 TLS 的 HTTP/2,即 h2)。
  5. HTTP/3(2022年)—— 突破 TCP 的限制
    • 底层传输由 TCP 改为 QUIC 协议(基于 UDP)
    • 解决 TCP 的队头阻塞:即使某个数据包丢失,也不影响其他流的数据交付。
    • 0-RTT 快速连接:首次握手后,后续连接可立即发送数据,大幅减少延迟。
    • 内置加密和传输可靠性,QUIC 本身提供类似 TLS 1.3 的加密和纠错机制。
    • 连接迁移:当用户从 WiFi 切换到移动网络时,连接 ID 不变,无需重建连接。

关键区别总结表

特性HTTP/1.0HTTP/1.1HTTP/2HTTP/3
连接复用无(每请求重建)持久连接(默认)多路复用(单连接)多路复用(单连接)
队头阻塞严重请求级(管道化无效)无(帧级别)无(流级别,基于UDP)
头部压缩HPACKQPACK
服务器推送
传输层TCPTCPTCPQUIC (UDP)
加密要求无(HTTPS可选)实际强制(TLS)强制(QUIC自带)
连接握手(新连接)3次TCP + 多RTT3次TCP + 多RTT3次TCP + TLS0-1 RTT(QUIC)
典型端口8080443(h2)443

实际使用建议

  • 当前仍广泛使用 HTTP/1.1,兼容性最好,适用于简单 API 或老旧系统。
  • HTTP/2 是现代 Web 的首选(配合 TLS),能极大提升页面加载速度。
  • HTTP/3 适用于对延迟敏感、弱网环境(如移动 APP、视频直播),但需要服务器和客户端同时支持(目前约 30% 流量已使用)。

1.3 HTTP 缓存

HTTP 缓存是一种减少冗余数据传输、降低服务器负载、提升页面加载速度的重要机制。它通过复用之前获取的资源,避免重复向源服务器请求相同内容。核心概念:两种缓存策略。

  1. 强缓存(强制缓存)
    • 无需与服务器通信,直接使用本地缓存
    • 由响应头中的 Cache-Control(HTTP/1.1)或 Expires(HTTP/1.0,已老旧)控制。
    • 状态码:强缓存命中时,浏览器直接返回 200 (from disk cache)200 (from memory cache),无网络请求。
  2. 协商缓存(对比缓存)
    • 与服务器通信,询问资源是否变更。若未变更,服务器返回 304 Not Modified(无响应体),节省带宽;若已变更,返回新资源(200)。
    • Last-Modified + If-Modified-Since
      • 服务器返回 Last-Modified: <最后修改时间>,浏览器后续请求携带 If-Modified-Since: <该时间>
      • 缺点:时间精度只能到秒,毫秒级变动无法感知;文件内容未改但时间变化会误触发更新。
    • ETag + If-None-Match(优先级更高):
      • 服务器返回一个唯一标识(如文件哈希),浏览器下次请求携带 If-None-Match: <该标识>。 可精确判断内容是否变化,推荐使用。
  3. 常见问题
    • Ctrl+F5(强制刷新):忽略所有缓存,请求头携带 Cache-Control: no-cachePragma: no-cache,协商缓存也失效。
    • 普通刷新(F5):跳过强缓存,但会携带协商缓存头(If-Modified-Since / If-None-Match)。
    • 后退/前进:可能直接使用强缓存。

1.4 HTTP 方法

HTTP 方法用于指示对指定资源执行的操作。每个请求方法都有其语义,并且一些方法具有 安全(不改变服务器状态)和 幂等(多次执行效果相同)的特性。

方法安全性幂等性说明
GET✅ 安全✅ 幂等请求指定的资源。不应有副作用,仅用于获取数据。
HEAD✅ 安全✅ 幂等与 GET 类似,但服务器只返回响应头(无响应体),常用于检查资源是否存在或获取元信息(如 Content-Length)。
POST❌ 不安全❌ 不幂等向服务器提交数据(如表单、上传文件),导致服务器状态变化。每次请求可能产生不同结果(例如多次提交生成多个订单)。
PUT❌ 不安全✅ 幂等用请求的载荷替换目标资源的所有内容。若资源不存在,部分实现会创建它。多次相同的 PUT 请求效果一致。
DELETE❌ 不安全✅ 幂等删除指定的资源。
PATCH❌ 不安全❌ 不幂等(通常)对资源进行部分修改。由于修改内容可能是增量(如 JSON Patch),多次相同请求可能效果不同,因此一般视为非幂等。
OPTIONS✅ 安全✅ 幂等返回服务器支持的 HTTP 方法(通过 Allow 响应头),用于 CORS 预检请求。
CONNECT❌ 不安全❌ 不幂等将连接转换为透明的 TCP 隧道,通常用于代理与 HTTPS 服务器建立隧道(由代理使用)。
TRACE✅ 安全✅ 幂等回显服务器收到的请求内容,主要用于调试(可能引发安全风险,许多生产环境禁用)。

额外说明

  • GET vs POST:GET 参数通过 URL 传递,长度有限且可见;POST 参数在请求体中,更安全(但非加密)且无大小限制。不要用 GET 执行修改操作(如删除)。
  • PUT vs POST:PUT 是“完整替换”,客户端知道资源最终 URL;POST 是“创建附属资源”或“处理非幂等操作”,由服务器决定最终 URL。
  • PATCH:通常使用 application/merge-patch+jsonapplication/json-patch+json 格式,描述变更指令。

实际开发中,RESTful API 主要使用 GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS。

1.5 HTTP 状态码

HTTP 状态码(Status Code)是服务器对客户端请求的响应结果标识,由三位数字组成,首位数字定义了响应类别。

分类范围含义描述
1xx100–101信息响应请求已接收,继续处理
2xx200–207成功响应请求成功完成
3xx300–308重定向需要进一步操作以完成请求
4xx400–451客户端错误请求有误或无法处理
5xx500–511服务器错误服务器处理请求时出错

常见状态码详解

  1. 1xx 信息类

    • 100 Continue:客户端应继续发送请求(用于 Expect: 100-continue)
    • 101 Switching Protocols:服务器同意升级协议(如 WebSocket)
  2. 2xx 成功类

    • 200 OK:请求成功,返回内容(取决于方法:GET返回资源,POST返回结果)
    • 201 Created:资源创建成功(常见于 POST/PUT),Location 头可指向新资源
    • 202 Accepted:请求已接收但未处理完(异步处理)
    • 204 No Content:成功但无返回体(常用于 DELETE、PUT 更新不返回数据)
    • 206 Partial Content:返回部分内容(用于断点续传、分块下载),配合 Range 头
  3. 3xx 重定向类

    • 301 Moved Permanently:资源永久移动到新 URL(后续应使用新地址)
    • 302 Found(HTTP/1.0 临时重定向):资源临时位于另一 URL,后续仍用原地址
    • 303 See Other:重定向到新 URL,且必须用 GET 请求(常用于 POST 后跳转结果页)
    • 304 Not Modified:资源未修改,可使用缓存(协商缓存命中时返回,无响应体)
    • 307 Temporary Redirect(HTTP/1.1):与 302 类似,但不允许改变请求方法(保持 POST→POST)
    • 308 Permanent Redirect(HTTP/1.1):与 301 类似,但不允许改变请求方法

    注意:302 在实践中有歧义,部分客户端会将 POST 改为 GET,推荐使用 303 或 307。

  4. 4xx 客户端错误类

    • 400 Bad Request:服务器无法理解请求(语法错误、参数错误、请求头过大等)
    • 401 Unauthorized:需要身份验证(未登录或凭证无效),响应头应包含 WWW-Authenticate
    • 403 Forbidden:服务器理解请求但拒绝执行(无权限,且不提供登录方式)
    • 404 Not Found:资源不存在(或服务器故意掩盖存在性)
    • 405 Method Not Allowed:请求方法不被允许(如 GET 要求但接口只支持 POST),响应头 Allow: GET, HEAD
    • 406 Not Acceptable:请求的 Accept 头要求的内容类型服务器无法提供
    • 408 Request Timeout:客户端未在服务器等待时间内发送完整请求
    • 409 Conflict:请求与当前资源状态冲突(如文件编辑冲突)
    • 410 Gone:资源已永久删除,类似 404 但明确表示“不再可用”
    • 413 Payload Too Large:请求体超过服务器限制
    • 415 Unsupported Media Type:请求的 Content-Type 不被支持
    • 418 I'm a teapot:愚人节彩蛋,源自茶壶超文本咖啡壶控制协议( RFC 2324)
    • 422 Unprocessable Content(WebDAV):语义正确但无法处理(例如参数校验失败)
    • 429 Too Many Requests:请求频率超限(常用于限流)
  5. 5xx 服务器错误类

    • 500 Internal Server Error:服务器内部错误(通用错误,无法定位具体问题)
    • 501 Not Implemented:服务器不支持请求的功能(如某个方法未实现)
    • 502 Bad Gateway:网关/代理服务器收到上游无效响应(如 PHP-FPM 挂掉)
    • 503 Service Unavailable:服务器暂时不可用(超载或维护),可包含 Retry-After
    • 504 Gateway Timeout:网关/代理等待上游响应超时
    • 505 HTTP Version Not Supported:服务器不支持请求中使用的 HTTP 版本

2. HTTP 进阶

2.1 Restful API

RESTful API 是一种遵循 REST(Representational State Transfer,表现层状态转移)架构风格的 API 设计规范。它不是协议或标准,而是一组设计原则,使 API 更简洁、可扩展、易理解。

RESTful API 的核心思想是:利用 HTTP 协议的能力,把一切操作抽象为对资源的管理

RESTful API 核心设计要素:

  1. 资源(Resource)

    • 一切都是资源,用 URI 标识(名词,而非动词)。
    • 示例:/users/orders/123/users/456/orders
  2. HTTP 方法(动作)

    方法用途示例
    GET获取资源GET /users → 用户列表
    POST创建子资源POST /users → 新增用户
    PUT完整替换资源(幂等)PUT /users/123 → 整体更新用户
    PATCH部分更新(非幂等)PATCH /users/123 → 修改邮箱
    DELETE删除资源DELETE /users/123 → 删除用户

RESTful API 最佳实践:

  1. URI 命名规范
    • 使用 复数名词/products 而非 /product
    • 多层路径:/authors/12/books
    • 避免动词:❌ /getUsers,✅ /users
    • / 表示层级,用 -_ 提高可读性,全部小写
    • 过滤/排序/分页使用查询参数:/users?role=admin&page=2&sort=name
  2. 安全注意事项
    • 敏感操作使用 HTTPS。
    • 认证常用方式:JWT、OAuth 2.0、API Key。
    • 对写操作进行 CSRF 防护;限制请求频率(rate limiting)。

2.2 HTTP 和 HTTPS 的区别

HTTP 与 HTTPS 的核心区别在于安全性,具体体现在以下几个方面:

对比维度HTTPHTTPS
加密传输明文传输,数据不加密使用 SSL/TLS 协议加密,数据密文传输
端口号默认 80默认 443
身份验证无服务器身份验证需向 CA(证书颁发机构)申请数字证书,验证服务器身份
篡改/监听风险高(中间人可轻松窃听、篡改)低(加密防窃听,摘要防篡改)
性能快(无加密握手)略慢(增加 TLS 握手及加解密损耗,但 HTTP/2 等可优化)
URL 前缀http://https://
SEO 与浏览器标识主流浏览器标记为“不安全”显示安全锁图标,利于搜索排名
  1. 工作原理简述
    • HTTP:直接基于 TCP 传输纯文本,请求/响应可被任意中间节点读取。
    • HTTPS = HTTP + SSL/TLS:先进行 TLS 握手(协商加密算法、交换证书、生成会话密钥),随后所有 HTTP 数据均用会话密钥加密传输。
  2. 实际建议
    • 任何涉及登录、支付、个人信息等敏感数据的场景必须使用 HTTPS。
    • 现代 Web 推荐全站 HTTPS,即使无敏感信息(可防止劫持、运营商广告注入)。
    • 启用 HTTPS 需要证书(可用 Let‘s Encrypt 免费获取)。

2.3 HTTP 和 TCP 长链接的区别

要理解 HTTP 长连接TCP 长连接 的区别,首先需要明确:HTTP 长连接本质上还是基于 TCP 的,只是两者关注的层次和细节不同。

  1. 基本定义

    • HTTP 长连接(通常称为 HTTP Keep‑Alive 或持久连接):在同一个 TCP 连接上连续发送多个 HTTP 请求/响应,避免每次请求都重新进行 TCP 三次握手和 TLS 握手。
    • TCP 长连接:指 TCP 连接建立后不立即关闭,而是保持打开状态,供上层应用(不限于 HTTP)多次发送数据。通常需要应用层或操作系统发送“心跳”来维持。
  2. 核心区别

    对比维度HTTP 长连接TCP 长连接
    协议层次应用层(HTTP 协议中的优化机制)传输层(TCP 协议本身的连接特性)
    控制方式通过 HTTP 头部 Connection: keep-aliveKeep-Alive: timeout=5, max=100 等协商由应用程序或操作系统通过 SO_KEEPALIVE 选项(TCP Keep‑Alive)或自定义心跳包来维持
    作用范围仅在 HTTP 请求/响应之间复用连接可用于任何基于 TCP 的协议(HTTP、SMTP、自定义协议等)
    典型超时设定通常较短(几秒到几分钟),由服务器配置(如 Nginx 的 keepalive_timeout通常较长(几小时甚至永久),或通过应用层心跳保活
    连接关闭一方发送 Connection: close 或达到超时/最大请求数后主动关闭需要应用明确调用 close(),或因为错误/超时而被动关闭
    对请求的处理一个 HTTP 长连接中,请求必须按照发送顺序依次响应(HTTP/1.1 存在队头阻塞)TCP 长连接可以承载任意顺序的二进制数据帧(如 HTTP/2 多路复用)
  3. 常见误解澄清

    • HTTP 长连接 ≠ TCP 长连接:HTTP Keep‑Alive 只是复用 TCP 连接的一种应用层约定;而 TCP 长连接是泛指连接被持续使用,不限于 HTTP。
    • TCP Keep‑Alive ≠ HTTP Keep‑Alive
      • TCP Keep‑Alive 是操作系统的空闲探测机制(默认通常关闭,开启后每隔一段时间发送空探测包,确认对端是否存活)。
      • HTTP Keep‑Alive 是应用层让连接不立即关闭的协商。
    • HTTP/2 和 HTTP/3 进一步改变了“长连接”的含义
      • HTTP/2 在一个 TCP 连接上实现多路复用,依然是 HTTP 长连接的延伸。
      • HTTP/3 基于 QUIC(UDP),不再依赖 TCP 长连接的概念,但内部有自己的连接复用与保活。
  4. 总结

    • HTTP 长连接是应用层对 TCP 连接的复用策略,目的是节省 HTTP 请求的建连开销。
    • TCP 长连接是传输层连接的生命周期特性,可能被任何上层协议使用。

    两者互不冲突:HTTP 长连接依赖于 TCP 长连接(不关连),但 TCP 长连接不必用于 HTTP。

3. HTTP 拓展

3.1 除了 HTTP 和 HTTPS,前端开发中还涉及到哪些通信协议

  1. WebSocket:WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。相比于传统的 HTTP 请求-响应模式,WebSocket 允许服务器主动向客户端发送数据,实现实时通信。在前端开发中,可以使用 WebSocket 协议来建立持久连接,实现实时聊天、实时数据更新等功能。
  2. WebRTC:WebRTC(Web 实时通信)是一项基于浏览器的实时通信技术,允许在浏览器之间进行点对点的音视频通信和数据传输,而无需借助插件或其他第三方软件。WebRTC 使用了多种协议和 API,包括实时传输协议(RTP)、会话描述协议(SDP)等。前端开发者可以利用 WebRTC 实现音视频通话、屏幕共享等实时通信应用。
  3. MQTT:MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议。它被设计用于低带宽、不稳定网络环境下的物联网设备通信。前端开发中,可以利用 MQTT 协议实现与物联网设备的通信,获取传感器数据、控制设备等。
  4. RESTful API:虽然 REST(Representational State Transfer)本身不是一种通信协议,但它是一种架构风格,常用于设计 Web API。RESTful API 使用标准的 HTTP 方法(如 GET、POST、PUT、DELETE)进行通信,通过请求资源的 URL 来表达操作,并使用 HTTP 状态码表示响应状态。前端开发者可以通过使用 RESTful API 与服务器进行数据交互。
  5. FTP(File Transfer Protocol):FTP 是一种用于在客户端和服务器之间传输文件的协议。在前端开发中,可以使用 FTP 协议来上传、下载和管理网站文件。
  6. SSH(Secure Shell):SSH 是一种加密的网络协议,用于远程登录到服务器并执行命令。前端开发人员可以使用 SSH 协议来通过终端或命令行界面连接到远程服务器,进行文件操作、运行程序等任务。
  7. DNS(Domain Name System):DNS 是一种用于将域名转换为 IP 地址的协议。在前端开发中,当用户输入一个域名时,浏览器会使用 DNS 协议将域名解析为相应的 IP 地址,以便建立与服务器的通信。

3.2 CORS 跨域是如何做的?从协议的角度去讲一下

CORS(跨域资源共享)是一种用于解决浏览器的同源策略限制,允许在不同域名之间进行跨域请求的机制。从协议的角度来看,CORS通过HTTP头部字段进行通信

以下是CORS的基本工作原理:

  1. 简单请求:对于简单请求(例如GET、POST、HEAD等),浏览器会在实际发送请求前,自动发送一个预检请求(Preflight request)来获取服务器的许可。预检请求是一个OPTIONS方法的HTTP请求,其中包含一些额外的头部字段。
  2. 预检请求:预检请求包含了一些关键信息,如请求方法、请求头、请求的目标URL等。服务器收到预检请求后,需要进行验证并返回响应,确认是否允许跨域请求。验证的方式包括检查Origin头部字段、Access-Control-Request-Method头部字段、Access-Control-Request-Headers头部字段等。
  3. 响应处理:如果服务器确认允许跨域请求,它会在响应中返回一些特定的头部字段,以授权浏览器访问响应的内容。这些头部字段包括Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers等。
  4. 安全限制:浏览器会根据响应头部字段进行安全限制,只有在响应中包含了正确的头部字段,浏览器才会允许跨域请求,并将响应的内容返回给前端。

需要注意的是,CORS机制只对浏览器发起的异步请求(如Ajax请求)有效,而对于直接在浏览器地址栏中输入URL的同步请求,则不会触发CORS限制。通过CORS机制,服务器可以灵活地控制哪些域名可以访问其资源,从而提高Web应用程序的安全性和可扩展性。

从协议的角度来看,CORS是通过HTTP头部字段进行通信的。具体来说,CORS使用了以下几个HTTP头部字段:

  1. Origin:表示浏览器发起请求的源地址(协议+域名+端口号),例如http://www.example.com
  2. Access-Control-Request-Method:表示浏览器实际发送的请求方法,例如GET、POST、PUT等。
  3. Access-Control-Request-Headers:表示浏览器实际发送的请求头部信息,例如Content-Type、Authorization等。
  4. Access-Control-Allow-Origin:表示服务器允许请求的源地址,可以是单个域名、多个域名、或者通配符*。
  5. Access-Control-Allow-Methods:表示服务器允许请求的方法,例如GET、POST、PUT等。
  6. Access-Control-Allow-Headers:表示服务器允许请求的头部信息,例如Content-Type、Authorization等。

当浏览器发起跨域请求时,它会自动在请求头部中添加Origin字段,告诉服务器请求的源地址。服务器在收到请求后,检查Origin字段,如果认为请求合法,则在响应头部中添加Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers字段,授权浏览器访问响应的内容。

4. WebSocket