HTTP 学习
侧边栏壁纸
  • 累计撰写 1 篇文章
  • 累计收到 0 条评论

HTTP 学习

左右
2024-01-01 / 0 评论 / 3 阅读 / 正在检测是否收录...

前情提要

今天在写学习 Nest 的时候,发现了 AI 推荐用 PUT PATCH DELECT 等方法,而不是一个劲的用 GET POST 去写接口,就复习下 HTTP 部分知识吧~~~

HTTP 基础核心概念

1.1 HTTP 是什么?

  • 浏览器和服务器沟通的规则
  • “无状态”协议
  • 基于请求 -> 响应模型

1.2 HTTP 的请求结构 Request

请求行(Request Line)
请求头(Headers)
请求体(Body)

示例:

POST /api/login HTTP/1.1
Content-Type: application/json
Authorization: Bearer xxx

{"username":"a", "password":"b"}

1.3 响应结构 Response

状态码(Status Code)
响应头(Headers)
响应体(Body)

HTTP 方法

CRUD 操作方法:

类型方法用途
创建POST新增资源
查询GET获取资源
全量更新PUT覆盖更新
局部更新PATCH修改部分字段
删除DELETE删除资源

➡️ 现在现代 REST API 大部分是 POST + PATCH

HTTP 状态码

三类前端最常用:
✔️ 200 ~ 299:成功类

  • 200 成功
  • 201 资源已创建(POST)
  • 204 无内容(DELETE、PUT 返回常见)

✔️ 400 ~ 499:前端问题

  • 400 参数格式错误
  • 401 未登录 / Token 过期
  • 403 权限不足
  • 404 找不到
  • 409 冲突(常见:已存在同名数据)
  • 422 校验失败(常见于 Laravel / Rails)

✔️ 500 ~ 599:后端问题

  • 500 服务器炸了
  • 502 Bad Gateway(Nginx 代理后端挂了)
  • 503 服务不可用
  • 504 超时

HTTP Header

4.1 身份认证类

header含义
AuthorizationJWT / Bearer Token
Cookie会话凭证

4.2 内容格式类

header含义
Content-Typebody 的格式(JSON / FORM)
Accept客户端需要返回什么格式

常见值:

① application/json(现代前后端常用)

Content-Type: application/json

特点:

  • 数据以 JSON 字符串传输
  • 结构化强,适合复杂对象
  • 服务端通常用 body-parser(Node)、JSON.parse 解析
  • axios 默认 JSON

优势:
✔️ 前后端分离最佳实践
✔️ 字段可嵌套
✔️ 跨语言通用格式

② application/x-www-form-urlencoded(传统表单)
浏览器表单默认的格式(key=value&key=value)

Content-Type: application/x-www-form-urlencoded

特点:

  • 不能嵌套复杂结构(嵌套会被序列化成 ab=1)
  • 占用空间小(URL 编码)
  • 一些老后台语言(PHP、Java Spring)习惯接收这个格式

③ multipart/form-data(文件上传必须用)

Content-Type: multipart/form-data; boundary=xxxx

特点:

  • 专门用于 文件 + 字段混合上传
  • 本质是分段(boundary)传输
  • 浏览器 FormData 会自动 set

4.3 缓存类

header含义
Cache-Control是否缓存、缓存多久
ETag资源版本号
If-None-Match用来配合 ETag 做缓存验证

4.4 CORS(跨域)

核心3个 header:

Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers

HTTP 缓存机制

分两种策略:
✔️ 强缓存(访问本地缓存,不发请求)

  • Cache-Control: max-age
  • Expires(老机制)

✔️ 协商缓存(资源变没变?)

  • ETag + If-None-Match
  • Last-Modified + If-Modified-Since

缓存命中 → 服务器返回 304

HTTP 与 HTTPS

6.1 HTTPS 解决了什么?

  • 明文变密文(防窃听)
  • 防篡改
  • 身份验证(可信任 CA)

6.2 TLS 握手流程(简版)

  1. 客户端 → 你好,我支持哪些加密方式
  2. 服务器 → 好,这是证书,这是加密方式
  3. 客户端 → 证书合法吗?OK,那用公钥加密一个秘钥给你
  4. 双方用同一个 symmetric key 通信

HTTP2、HTTP3

HTTP/2 的特点

  • 多路复用(双向并发,不阻塞)
  • 头部压缩
  • 二进制帧
  • 服务端推送(HTTP3 已废弃)

HTTP/3(基于 QUIC)

  • 不再用 TCP → 使用 UDP
  • 彻底解决队头阻塞
  • 建连快、移动端体验更好

身份与鉴权模式

Cookie + Session(状态化)

🌟 概念

  • Session 存在服务端(内存 / Redis)
  • 浏览器自动携带 Cookie(sessionId)
  • 服务器根据 sessionId 找到用户登录状态

🌟 前端使用方式

  • 浏览器自动带 cookie(无需写代码)
  • 需要注意 withCredentials(跨域时 axios 必须带上)
axios.get('/api/user', { withCredentials: true })

🌟 优点

  • 安全性强(Session 在服务端,不会被伪造)
  • 注销简单(清 session)

🌟 缺点

  • 服务端需要维护 Session → 成本高
  • 分布式架构要做 session 共享(Redis)

🌟 Vue/React SPA 基本不会再用(除非企业老系统)

Token / JWT(无状态化)

现代 Web & 移动端的主流。

🌟 概念

  • 前端保存 Token(LocalStorage / Cookie)
  • 请求时通过 Authorization: Bearer xxx
  • 服务端根据 token 解密出用户信息

🌟 为什么前端喜欢 JWT?

  • 不依赖 Cookie
  • 不需要服务端存状态
  • 适合:

    • 移动端
    • 多端统一 API
    • 微服务

🌟 缺点

  • Token 被盗 → 攻击者长期有效
    → 解决:短 Token + Refresh Token

OAuth2 / OpenID Connect(现代企业级鉴权)

用于第三方登录:

  • 微信登录
  • GitHub 登录
  • Google 登录

区别:

  • OAuth2 → 授权(获取资源权限)
  • OIDC → 身份认证 + 授权(可直接获取用户身份)

适合:

  • 企业内部系统
  • 单点登录(SSO)

API Key / HMAC(服务端之间调用)

前端不常用,更多是后端服务、支付平台 Webhook。

  • API Key:简单、不太安全(纯字符串)
  • HMAC:带签名校验、不可伪造,安全性强

例如:

X-Signature: HMAC_SHA256(secret, timestamp + body)

跨域(CORS)

你遇到 CORS 的 90% 情况都是前端开发环境 + 后端未配置。

简单请求与预检请求

简单请求(不会触发 OPTIONS)

必须满足三个条件之一:

  1. 方法:GET / POST / HEAD
  2. Content-Type 仅限:

    • text/plain
    • application/x-www-form-urlencoded
    • multipart/form-data
  3. 没有自定义 Header

任意一点不满足 → 自动触发 OPTIONS 预检请求

例如带:

Authorization: Bearer xxx

一定触发预检。

CORS 三大关键响应头

后端必须返回:

1)Access-Control-Allow-Origin

允许的域名

Access-Control-Allow-Origin: https://example.com

不能写 * + Cookie 一起使用。

2)Access-Control-Allow-Credentials

允许跨域带 cookie

Access-Control-Allow-Credentials: true

3)Access-Control-Allow-Headers

允许的自定义 header

Access-Control-Allow-Headers: Authorization, Content-Type

常见解决方案

✔ 方案 1:后端开启 CORS(最佳)

Node/Nest:

app.enableCors({
  origin: 'http://localhost:3000',
  credentials: true,
})

✔ 方案 2:Nginx 反向代理(生产常用)

让 API 和前端变成同一个域名。

✔ 方案 3:开发环境 proxy

Vite:

server: {
  proxy: {
    '/api': 'http://localhost:3001'
  }
}

性能优化点

CDN + 静态资源长缓存

核心思想:

  • 静态资源 -> 不要变
  • 如果变 -> 通过文件名 hash 做版本号

例如:

app.abcd1234.js
app.abcd5678.js

CDN + 缓存头:

Cache-Control: max-age=31536000, immutable

HTTP2 多路复用

特点:

  • 一个 TCP 链接上同时传多个请求,不阻塞
  • Header 压缩
  • 二进制帧

压缩(gzip / brotli)

Nginx:

brotli on;
gzip on;

预加载 / 预连接

提升首屏性能的关键。

🌟 DNS-prefetch

提前解析域名

<link rel="dns-prefetch" href="//cdn.xxx.com">

🌟 preconnect

提前建立 TCP/TLS 连接

<link rel="preconnect" href="https://cdn.xxx.com">

🌟 preload

强制预加载关键资源

<link rel="preload" href="/main.css" as="style" />

🌟 prefetch

提前加载未来可能要用的资源(不会阻塞)

<link rel="prefetch" href="/page.js">

API 设计(REST / GraphQL / gRPC)

RESTful 设计

核心理念:

  • URL 表示资源
  • 方法表示操作
  • 状态码表示结果

例:

POST /products       # 创建商品
GET /products/:id    # 查询
PATCH /products/:id  # 更新
DELETE /products/:id # 删除

版本化(常见):

/api/v1/
/api/v2/

常见误用:

❌ POST /products/updateProduct
✔️ 使用资源语义:

PATCH /products/:id

GraphQL

适合复杂查询场景,比如:

  • 前端需要组合多个资源
  • 后端多表聚合
  • 客户端定制化查询

优势:

  • 请求一个 endpoint 自由选择字段(避免 over-fetch / under-fetch)
  • 强类型 schema

缺点:

  • 后端门槛高
  • 缓存难
  • 不适合高并发简单业务(REST 更强)

适合大型产品前端团队。

gRPC(内部服务通信)

  • 使用 HTTP/2
  • ProtoBuf 比 JSON 更小更快
  • 适合 后端微服务之间 调用

前端通常接触不到,除非:

  • Web → gRPC-Web(特殊场景)
  • Electron / 移动端 App
0

评论 (0)

取消