← 返回计算机网络总览

🔐 HTTP/HTTPS 原理面试题

掌握 Web 通信协议与安全机制

📚 HTTP/HTTPS 核心知识

1. HTTP 请求和响应的完整结构是什么?简单

HTTP 请求结构

请求行(Request Line)
GET /api/users HTTP/1.1

请求头(Request Headers)
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Content-Type: application/json
Cookie: session_id=abc123

空行(CRLF)

请求体(Request Body)- 可选
{"username": "john", "password": "123456"}

HTTP 响应结构

状态行(Status Line)
HTTP/1.1 200 OK

响应头(Response Headers)
Content-Type: application/json
Content-Length: 1234
Set-Cookie: session_id=xyz789
Cache-Control: max-age=3600

空行(CRLF)

响应体(Response Body)
{"id": 1, "name": "John Doe"}

关键组成部分

  • 请求行/状态行:方法、URL、版本 / 版本、状态码、状态描述
  • Headers:键值对形式的元数据
  • 空行:分隔头部和主体
  • Body:实际传输的数据(GET 请求通常没有 body)
2. 常见的 HTTP 方法有哪些?它们的区别和使用场景是什么?简单

HTTP 方法对比

方法幂等性安全性可缓存用途
GET获取资源
POST部分创建资源、提交数据
PUT更新资源(完整替换)
PATCH部分更新资源
DELETE删除资源
HEAD获取响应头(不返回 body)
OPTIONS查询支持的方法(CORS 预检)

关键概念

  • 幂等性:多次执行结果相同(GET、PUT、DELETE 是幂等的)
  • 安全性:不修改服务器状态(GET、HEAD、OPTIONS 是安全的)
  • 可缓存:响应可以被缓存

RESTful API 设计

GET    /users          # 获取用户列表
GET    /users/123      # 获取单个用户
POST   /users          # 创建用户
PUT    /users/123      # 完整更新用户
PATCH  /users/123      # 部分更新用户
DELETE /users/123      # 删除用户

GET vs POST

特性GETPOST
参数位置URL 查询字符串请求体
长度限制有(浏览器/服务器限制)无(理论上)
可见性URL 可见,不安全相对安全
缓存可缓存默认不缓存
书签可保存为书签不可以
历史记录保留在浏览器历史不保留
3. 常见的 HTTP 状态码有哪些?它们分别代表什么含义?简单

HTTP 状态码分类

  • 1xx:信息性状态码(请求已接收,继续处理)
  • 2xx:成功状态码(请求已成功处理)
  • 3xx:重定向状态码(需要进一步操作)
  • 4xx:客户端错误(请求有误)
  • 5xx:服务器错误(服务器处理失败)

常见状态码详解

状态码含义说明
200OK请求成功
201Created资源创建成功(POST)
204No Content成功但无返回内容(DELETE)
301Moved Permanently永久重定向
302Found临时重定向
304Not Modified资源未修改,使用缓存
400Bad Request请求语法错误
401Unauthorized未认证(需要登录)
403Forbidden无权限访问
404Not Found资源不存在
405Method Not Allowed方法不允许
429Too Many Requests请求过多(限流)
500Internal Server Error服务器内部错误
502Bad Gateway网关错误
503Service Unavailable服务不可用
504Gateway Timeout网关超时

301 vs 302

  • 301:永久重定向,搜索引擎会更新索引,浏览器会缓存
  • 302:临时重定向,搜索引擎不更新索引
  • 使用场景:
    • 301:网站迁移、URL 规范化
    • 302:临时维护、A/B 测试

401 vs 403

  • 401:未认证,需要提供身份凭证(如登录)
  • 403:已认证但无权限,即使登录也无法访问
4. HTTP/1.0、HTTP/1.1、HTTP/2、HTTP/3 有什么区别?中等

HTTP 版本演进

特性HTTP/1.0HTTP/1.1HTTP/2HTTP/3
发布年份1996199920152022
连接短连接长连接多路复用多路复用
传输协议TCPTCPTCPUDP (QUIC)
头部压缩HPACKQPACK
服务器推送
队头阻塞有(TCP 层)

HTTP/1.0 → HTTP/1.1 改进

  • 持久连接(Keep-Alive):默认开启,复用 TCP 连接
  • 管道化(Pipelining):可同时发送多个请求(但响应仍需按序)
  • Host 头:支持虚拟主机
  • 缓存控制:Cache-Control、ETag
  • 断点续传:Range 头支持
  • 新增方法:PUT、PATCH、DELETE、OPTIONS

HTTP/2 核心特性

  • 二进制分帧:不再是文本协议,更高效
  • 多路复用:一个连接并发处理多个请求/响应
  • 头部压缩(HPACK):减少重复头部传输
  • 服务器推送:主动推送资源(如 CSS、JS)
  • 流优先级:可设置请求优先级
# HTTP/1.1 - 多个请求需要多个连接或串行
Connection 1: GET /index.html
Connection 2: GET /style.css
Connection 3: GET /script.js

# HTTP/2 - 一个连接并发处理
Connection 1:
  Stream 1: GET /index.html
  Stream 2: GET /style.css
  Stream 3: GET /script.js

HTTP/3 (QUIC) 革新

  • 基于 UDP:避免 TCP 队头阻塞
  • 0-RTT 连接:更快的连接建立
  • 连接迁移:IP 变化不影响连接(移动网络友好)
  • 内置加密:默认 TLS 1.3
  • 独立流:一个流丢包不影响其他流

为什么 HTTP/2 还有队头阻塞?

HTTP/2 解决了应用层的队头阻塞,但 TCP 层仍存在:

  • TCP 保证顺序传输,一个包丢失会阻塞后续所有包
  • HTTP/3 使用 QUIC(UDP),每个流独立,彻底解决
5. HTTPS 的工作原理是什么?SSL/TLS 握手过程是怎样的?中等

HTTPS = HTTP + SSL/TLS

HTTPS 在 HTTP 和 TCP 之间加入 SSL/TLS 层,提供加密、认证和完整性保护。

TLS 1.2 握手流程(完整版)

  1. Client Hello:
    • 支持的 TLS 版本
    • 支持的加密套件列表
    • 客户端随机数(Client Random)
  2. Server Hello:
    • 选择的 TLS 版本
    • 选择的加密套件
    • 服务器随机数(Server Random)
  3. Certificate:服务器发送数字证书(包含公钥)
  4. Server Key Exchange:(可选)DH 参数
  5. Server Hello Done:服务器握手消息结束
  6. Client Key Exchange:
    • 客户端生成预主密钥(Pre-Master Secret)
    • 用服务器公钥加密后发送
  7. 生成会话密钥:
    • 双方使用 Client Random + Server Random + Pre-Master Secret
    • 通过 PRF 函数生成对称密钥
  8. Change Cipher Spec:通知对方后续使用加密通信
  9. Finished:发送加密的握手摘要,验证握手完整性
  10. Application Data:开始加密通信
# TLS 1.2 握手(简化)
Client                                Server
  |                                      |
  |--- Client Hello ------------------>  |
  |                                      |
  |<-- Server Hello -------------------|  |
  |<-- Certificate --------------------|  |
  |<-- Server Hello Done --------------|  |
  |                                      |
  |--- Client Key Exchange ----------->  |
  |--- Change Cipher Spec ------------>  |
  |--- Finished ----------------------->  |
  |                                      |
  |<-- Change Cipher Spec -------------|  |
  |<-- Finished -----------------------|  |
  |                                      |
  |<-- Encrypted Application Data ---->  |

TLS 1.3 改进(1-RTT)

  • 简化握手流程,只需 1-RTT(往返)
  • 移除不安全的加密算法
  • 支持 0-RTT(会话恢复时)
# TLS 1.3 握手(1-RTT)
Client                                Server
  |                                      |
  |--- Client Hello ------------------>  |
  |    (包含密钥交换参数)                  |
  |                                      |
  |<-- Server Hello -------------------|  |
  |<-- Certificate --------------------|  |
  |<-- Finished -----------------------|  |
  |                                      |
  |--- Finished ----------------------->  |
  |                                      |
  |<-- Encrypted Application Data ---->  |

加密方式

  • 非对称加密(RSA/ECDHE):握手阶段,交换密钥
  • 对称加密(AES):数据传输阶段,高效加密
  • 哈希算法(SHA-256):完整性校验

数字证书验证

  1. 浏览器检查证书是否过期
  2. 验证证书域名是否匹配
  3. 检查证书是否被吊销(CRL/OCSP)
  4. 验证证书链,追溯到受信任的根 CA
6. Cookie、Session 和 Token 的区别是什么?各自的优缺点?中等

三种会话管理方式对比

特性CookieSessionToken (JWT)
存储位置客户端(浏览器)服务器客户端
数据大小4KB 限制无限制较大(包含用户信息)
安全性较低(可被窃取)较高中等(需防止泄露)
跨域受同源策略限制受限支持
服务器压力需存储
扩展性差(需共享存储)

Cookie 详解

# 服务器设置 Cookie
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Strict

# 浏览器自动携带 Cookie
Cookie: session_id=abc123

Cookie 属性:

  • Domain:Cookie 的域名
  • Path:Cookie 的路径
  • Expires/Max-Age:过期时间
  • HttpOnly:禁止 JavaScript 访问(防 XSS)
  • Secure:仅 HTTPS 传输
  • SameSite:防 CSRF 攻击
    • Strict:完全禁止第三方请求携带
    • Lax:部分允许(GET 导航)
    • None:允许(需配合 Secure)

Session 工作流程

  1. 用户登录,服务器创建 Session,生成 Session ID
  2. Session ID 通过 Cookie 返回给客户端
  3. 客户端后续请求携带 Session ID
  4. 服务器根据 Session ID 查找用户信息

Session 存储方案:

  • 内存:快但不持久,重启丢失
  • Redis:高性能,支持分布式
  • 数据库:持久化,性能较低

JWT Token 结构

# JWT 格式:Header.Payload.Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

# Header(Base64 编码)
{
  "alg": "HS256",
  "typ": "JWT"
}

# Payload(Base64 编码)
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622
}

# Signature(签名)
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

JWT 优点:

  • 无状态,服务器不存储
  • 支持跨域
  • 适合分布式系统

JWT 缺点:

  • 无法主动失效(除非加黑名单)
  • Token 较大,增加传输开销
  • Payload 不加密,不能存敏感信息

如何选择?

  • 传统 Web 应用:Cookie + Session
  • 前后端分离:Token (JWT)
  • 移动端 App:Token
  • 微服务:Token(无状态,易扩展)
7. HTTP 缓存机制是什么?强缓存和协商缓存的区别?中等

HTTP 缓存分类

  • 强缓存:直接使用本地缓存,不发请求
  • 协商缓存:向服务器确认缓存是否有效

强缓存(Expires / Cache-Control)

# Expires(HTTP/1.0,已过时)
Expires: Wed, 21 Oct 2025 07:28:00 GMT

# Cache-Control(HTTP/1.1,推荐)
Cache-Control: max-age=3600  # 缓存 3600 秒
Cache-Control: no-cache      # 需要协商缓存
Cache-Control: no-store      # 完全不缓存
Cache-Control: public        # 可被任何缓存存储
Cache-Control: private       # 只能被浏览器缓存

Cache-Control 指令:

  • max-age=N:缓存 N 秒
  • s-maxage=N:CDN/代理缓存时间
  • no-cache:使用前必须验证
  • no-store:禁止缓存
  • must-revalidate:过期后必须验证

协商缓存(Last-Modified / ETag)

方式一:Last-Modified / If-Modified-Since

# 首次请求
Response:
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT

# 再次请求
Request:
If-Modified-Since: Wed, 21 Oct 2024 07:28:00 GMT

# 未修改
Response:
304 Not Modified

# 已修改
Response:
200 OK
Last-Modified: Wed, 21 Oct 2024 08:00:00 GMT
(新内容)

方式二:ETag / If-None-Match(更精确)

# 首次请求
Response:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

# 再次请求
Request:
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

# 未修改
Response:
304 Not Modified

缓存流程

  1. 浏览器发起请求
  2. 检查强缓存(Cache-Control/Expires)
    • 未过期 → 直接使用缓存(200 from cache)
    • 已过期 → 进入协商缓存
  3. 协商缓存(ETag/Last-Modified)
    • 未修改 → 304 Not Modified
    • 已修改 → 200 OK + 新内容

实战配置

# Nginx 配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d;  # 静态资源缓存 30 天
    add_header Cache-Control "public, immutable";
}

location ~* \.(html)$ {
    expires -1;  # HTML 不缓存
    add_header Cache-Control "no-cache, no-store, must-revalidate";
}

最佳实践

  • 静态资源:文件名带 hash,强缓存 + 长过期时间
  • HTML:协商缓存或不缓存
  • API 接口:通常不缓存或短时间缓存
8. 什么是 CORS?如何解决跨域问题?简单

同源策略

浏览器安全机制,限制不同源之间的资源访问。

同源定义:协议、域名、端口完全相同

# 同源
http://example.com/page1
http://example.com/page2

# 不同源
http://example.com      vs https://example.com  (协议不同)
http://example.com      vs http://api.example.com  (域名不同)
http://example.com:80   vs http://example.com:8080  (端口不同)

CORS(Cross-Origin Resource Sharing)

跨域资源共享,通过 HTTP 头部允许跨域访问。

简单请求

满足以下条件的请求:

  • 方法:GET、HEAD、POST
  • 头部:Accept、Accept-Language、Content-Language、Content-Type(仅限 application/x-www-form-urlencoded、multipart/form-data、text/plain)
# 请求
GET /api/data HTTP/1.1
Origin: http://example.com

# 响应
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Credentials: true

预检请求(Preflight)

非简单请求会先发送 OPTIONS 请求:

# 预检请求
OPTIONS /api/data HTTP/1.1
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

# 预检响应
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400  # 缓存预检结果 24 小时

# 实际请求
PUT /api/data HTTP/1.1
Origin: http://example.com
Content-Type: application/json

CORS 响应头

  • Access-Control-Allow-Origin:允许的源(* 或具体域名)
  • Access-Control-Allow-Methods:允许的方法
  • Access-Control-Allow-Headers:允许的请求头
  • Access-Control-Allow-Credentials:是否允许携带 Cookie
  • Access-Control-Max-Age:预检结果缓存时间

其他跨域解决方案

  • JSONP:利用 script 标签不受同源限制(仅支持 GET)
  • 代理:前端请求同源代理服务器,代理服务器转发
  • Nginx 反向代理:统一域名,后端分发
  • postMessage:iframe 跨域通信
// Spring Boot CORS 配置
@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                    .allowedOrigins("http://example.com")
                    .allowedMethods("GET", "POST", "PUT", "DELETE")
                    .allowedHeaders("*")
                    .allowCredentials(true)
                    .maxAge(3600);
            }
        };
    }
}
9. 如何优化 Web 应用的 HTTP 性能?请列举至少 10 种方法。中等

HTTP 性能优化策略

1. 减少请求数量

  • 合并 CSS/JS 文件
  • 使用 CSS Sprites(雪碧图)
  • 使用字体图标(Icon Font)
  • 内联关键 CSS

2. 减小资源体积

  • 压缩 CSS/JS(Minify)
  • 图片压缩(TinyPNG、WebP)
  • 启用 Gzip/Brotli 压缩
  • Tree Shaking(移除未使用代码)

3. 利用缓存

  • 强缓存(Cache-Control)
  • 协商缓存(ETag)
  • Service Worker 缓存
  • CDN 缓存

4. 优化加载策略

  • 懒加载(Lazy Loading)
  • 预加载(Preload)
  • 预连接(Preconnect)
  • DNS 预解析(DNS Prefetch)

5. 使用 CDN

  • 静态资源分发到边缘节点
  • 就近访问,减少延迟
  • 分担源站压力

6. 升级协议

  • HTTP/2:多路复用、头部压缩
  • HTTP/3:QUIC 协议,更快

7. 优化关键渲染路径

  • CSS 放 head,JS 放 body 底部
  • async/defer 异步加载 JS
  • 减少首屏渲染阻塞

8. 资源优先级

  • 关键资源优先加载
  • 非关键资源延迟加载
  • 使用 Resource Hints

9. 减少重定向

  • 每次重定向增加一次 RTT
  • 直接返回最终 URL

10. 使用长连接

  • HTTP Keep-Alive
  • WebSocket(实时通信)
















10. HTTP 短连接和长连接有什么区别?Keep-Alive 与连接复用如何工作?中等

短连接 vs 长连接

  • 短连接:一次请求/响应后就关闭 TCP 连接(HTTP/1.0 默认)。
  • 长连接:同一个 TCP 连接上可以承载多个请求/响应(HTTP/1.1 默认)。

Keep-Alive 机制

# 客户端请求
GET /index.html HTTP/1.1
Host: www.example.com
Connection: keep-alive

# 服务器响应
HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: timeout=5, max=100
  • timeout:连接空闲多长时间后关闭。
  • max:一个连接最多复用多少个请求。

连接复用

  • HTTP/1.1:同一连接按顺序处理多个请求,仍可能队头阻塞。
  • HTTP/2:一个连接上并发多个流,实现真正的多路复用。

实践建议

  • 对后端服务开启 Keep-Alive,可以显著减少三次握手开销。
  • 合理设置空闲超时,避免过多空闲连接占用资源。
11. WebSocket 与 HTTP 有什么关系和区别?适用于哪些场景?中等

WebSocket 与 HTTP 的关系

  • WebSocket 握手阶段基于 HTTP,使用 Upgrade: websocket 头升级协议。
  • 握手完成后,变成独立的全双工协议,不再走 HTTP 请求/响应模式。

特性对比

维度HTTPWebSocket
通信模式请求-响应双向实时通信
连接短连接/长连接长连接
消息方向通常由客户端发起任意一方可主动发送
典型场景普通页面、REST APIIM、实时推送、协同编辑

使用示例

// 浏览器端示例 const ws = new WebSocket('wss://example.com/ws'); ws.onopen = () => ws.send('hello'); ws.onmessage = (evt) => console.log('msg:', evt.data); ws.onclose = () => console.log('closed');

适用场景

  • 聊天室、在线客服、游戏房间等 IM 场景。
  • 行情推送、比赛比分、直播弹幕等实时数据。
  • 在线协同编辑、在线白板。
12. HTTP 相关的常见安全风险有哪些?你在项目中是如何防护 XSS、CSRF 和请求劫持的?困难

常见 HTTP 相关安全风险

  • XSS:注入恶意脚本,窃取 Cookie 或伪造页面。
  • CSRF:利用用户已登录状态,伪造敏感操作请求。
  • 请求劫持:DNS 劫持、HTTP 劫持、中间人攻击。

XSS 防护

  • 统一使用输出编码(HTML/JS 编码),避免直接拼接到 innerHTML
  • Cookie 设置 HttpOnly,防止被脚本读取。
  • 开启 CSP(Content-Security-Policy)限制脚本来源和内联脚本。

CSRF 防护

  • 表单/接口增加 CSRF Token,后端校验 Token 有效性。
  • Cookie 使用 SameSite=Lax/Strict,减少第三方请求自动携带 Cookie。
  • 对转账、修改密码等关键操作增加二次确认或短信验证码。

请求劫持防护

  • 全站启用 HTTPS,并配置 HSTS。
  • 避免在 URL 中透传敏感参数,敏感信息放在请求体或头部。
  • 通过 X-Frame-Options / frame-ancestors 防止点击劫持。

面试时可以结合自己项目的安全加固实践来讲,例如「统一接入 WAF、防爬限流、登录网关与单点登录」等,会比单纯背诵概念更有说服力。