HTTP 全解:一文掌握请求/响应、缓存机制、登录态与跨域

0 阅读9分钟

深入理解 HTTP 协议(含 Cookie 与 JWT)

1. 为什么需要 HTTP?

在 Web 环境中,客户端(如浏览器)与服务器需要交换信息。若没有统一规则,不同厂商的软件无法互操作。HTTP(HyperText Transfer Protocol,超文本传输协议)定义了:

  • 请求的格式(方法、路径、头部、正文)
  • 响应的格式(状态码、头部、正文)
  • 资源定位方式(URL)
  • 连接管理、缓存控制、状态保持等机制

简单来说:HTTP 是浏览器与服务器之间约定的“通信语言”,确保双方能准确理解对方意图。

2. HTTP 版本演进

版本核心特性主要局限
HTTP/0.9仅 GET 方法,只能返回纯文本(如早期的 HTML)功能极简,无法传输图片或样式
HTTP/1.0引入状态码、头部、POST/HEAD 方法短连接:每次请求需重新建立 TCP 连接
HTTP/1.1持久连接(keep-alive)、管道化、Host 头队头阻塞:同一连接上的请求必须串行响应
HTTP/2二进制分帧、多路复用、头部压缩、服务器推送TCP 层面的队头阻塞仍存在
HTTP/3基于 QUIC(UDP)尚未完全普及

每个新版本都在解决前一版本的核心瓶颈。

3. HTTP 报文结构

3.1 请求报文

POST /api/user HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 18

{"name":"Alice"}

组成:

  • 请求行:方法、请求目标、HTTP版本
  • 头部字段:键值对
  • 空行:分隔头部与正文
  • 消息正文:可选

3.2 响应报文

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

{"id":1,"name":"Alice"}

组成:

  • 状态行:HTTP版本、状态码、原因短语
  • 头部字段、空行、正文(同上)

4. HTTP 方法(动作语义)

方法语义是否携带主体
GET获取资源
HEAD仅获取响应头部
POST创建资源
PUT全量替换资源
PATCH部分更新资源
DELETE删除资源可有可无
OPTIONS查询服务器支持的方法

语义核心:GET 用于读取,POST 用于创建,PUT/PATCH 用于更新,DELETE 用于删除。

5. HTTP 状态码分类

类别范围含义典型示例
1xx100-101信息性响应100 Continue
2xx200-206成功200 OK,204 No Content
3xx300-308重定向301 永久搬家,302 临时跳转,304 未修改
4xx400-451客户端错误400 错误请求,401 未认证,403 禁止,404 未找到
5xx500-511服务器错误500 内部错误,503 服务不可用

速记:2xx 成功,3xx 去别处,4xx 你错了,5xx 它错了。

6. HTTPS 的安全机制

HTTP 是明文传输,存在窃听、篡改、冒充三大风险。HTTPS = HTTP + TLS/SSL,在 TCP 与 HTTP 之间增加安全层。

风险解决方案
窃听(内容被看)混合加密(非对称交换对称密钥,对称加密数据)
篡改(内容被改)消息认证码校验完整性
冒充(假网站)数字证书(CA 签发),验证服务器身份

结论:HTTPS 比 HTTP 多了加密、认证、完整性保护三层机制。

7. HTTP 缓存机制

缓存可减少重复请求,提升性能。分为两类:

类型控制字段行为
强制缓存Cache-Control: max-age=3600、Expires有效期内直接使用本地副本,不发请求
协商缓存ETag / If-None-Match、Last-Modified / If-Modified-Since向服务器验证资源是否过期;若未变化返回 304

缓存相关头的优先级为: Cache-Control 大于 Expires;服务器验证资源时,通常优先校验 ETag,再验证 Last-Modified。

流程图如下:

8. 一次完整的 HTTP 事务

从输入 URL 到页面展示(HTTP 相关部分):

  1. DNS 解析:域名 → IP 地址。
  2. TCP 连接:三次握手建立连接。
  3. 发送请求:浏览器构建 HTTP 请求报文,通过 TCP 发送。
  4. 服务器处理:解析请求,执行逻辑,生成响应。
  5. 返回响应:服务器发送 HTTP 响应报文。
  6. 浏览器处理: 拿到 HTML 后开始关键渲染。
  7. 连接管理:若 Connection: keep-alive,连接保持;否则关闭连接。

若为 HTTPS,则在 TCP 连接后增加 TLS 握手(证书验证、密钥协商)。

完整流程如下图:

HTTP 事务完成后,浏览器进入渲染流程(详见《深入理解浏览器渲染流程》),如下图所示:

9. 状态保持机制:Cookie 与 JWT

HTTP 本身是无状态协议——每个请求都是独立的。为了实现登录状态等功能,需要在请求之间传递身份标识。Cookie 和 JWT 是两种主流的解决方案。

9.1 Cookie

Cookie 是服务器通过 Set-Cookie 头部要求浏览器保存的文本。浏览器在后续同源请求中自动携带。

工作流程

  1. 服务器响应:Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure
  2. 浏览器保存该 Cookie。
  3. 后续请求自动携带:Cookie: sessionId=abc123

常用属性

属性作用
Expires / Max-Age控制有效期
Path限制作用路径
Domain限制作用域名
HttpOnly禁止 JavaScript 访问(防 XSS:在你页面执行恶意 JS )
Secure仅在 HTTPS 下传输,开启后,即使用户不小心访问了 HTTP 版本的网站,浏览器也会自动丢弃该 Cookie ,Secure 不直接防 CSRF,但它是构建安全登录体系的基础,配合 <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">SameSite</font> 才能构成完整防御
SameSite限制 Cookie 只在本网站发送,跨站请求不自动带 Cookie,控制跨站请求是否携带(防 CSRF)

优点:浏览器自动管理。
缺点:跨域支持复杂,有 CSRF 风险。(攻击者利用你已经在目标网站登录的登录状态,在别的恶意页面里,偷偷替你发起操作请求)

9.2 JWT(JSON Web Token)

JWT 是一种紧凑的令牌格式。服务器登录后返回加密签名字符串,客户端后续请求手动携带。

JWT 结构xxxxx.yyyyy.zzzzz,三部分组成:

  • Header:我是什么类型、用什么算法
  • Payload:我带了什么数据(公开可见)
  • Signature:我没被篡改(服务器密钥保证)

工作流程

  1. 用户登录,服务器验证成功后生成 JWT 并返回。
  2. 客户端保存 JWT(通常存于 localStorage)。
  3. 客户端在后续请求头部添加:Authorization: Bearer <JWT>
  4. 服务器验证签名,读取用户信息。

优点

  • 无状态,易于水平扩展。
  • 跨域友好。
  • 自包含用户信息。

缺点

  • 无法主动注销(过期前始终有效)。
  • 体积较大。
  • 存于 localStorage 时易受 XSS 攻击。

9.3 Cookie vs JWT 对比

维度CookieJWT
存储位置浏览器自动存储(可设 HttpOnly)前端手动存储(通常 localStorage)
传输方式自动携带(Cookie 头)手动放入 Authorization 头
跨域支持需配置 withCredentials 和 CORS配置简单 (只需基础 CORS)
状态管理服务端存储会话(有状态)服务端无状态(令牌自包含)
安全风险CSRFXSS
主动注销服务端删除会话即可需引入黑名单或缩短有效期
适用场景传统 Web 应用(同域)移动端、微服务、跨域 API

10. 跨域(CORS)

10.1 为什么会有跨域?

浏览器的同源策略(Same-Origin Policy)限制:协议、域名、端口三者任意一个不同,即为跨域。同源策略的目的是防止恶意脚本读取其他网站的数据(如窃取 Cookie、劫持登录状态)。

10.2 跨域解决方案

方案原理适用场景
CORS(跨域资源共享)服务器设置响应头 Access-Control-Allow-Origin 允许指定源访问标准方案,支持所有请求方法,需后端配合
JSONP利用 <script> 标签不受同源限制,只支持 GET老旧浏览器兼容,仅 GET 请求
代理服务器前端请求同源代理,代理转发到目标服务器开发环境(webpack devServer)、生产环境(nginx)
postMessage跨窗口通信 API不同源的 iframe 或弹出窗口通信
WebSocket原生支持跨域实时双向通信

10.3 CORS 核心响应头

响应头作用
Access-Control-Allow-Origin允许的源(* 或具体域名)
Access-Control-Allow-Methods允许的 HTTP 方法(GET, POST, PUT, DELETE 等)
Access-Control-Allow-Headers允许的自定义请求头
Access-Control-Allow-Credentials是否允许携带 Cookie(设为 true 时,Allow-Origin 不能为 *
Access-Control-Max-Age预检请求(OPTIONS)的缓存时间(秒)

10.4 预检请求(OPTIONS)

什么是预检请求?

预检请求是在跨域的前提下,浏览器在发送非简单请求前,自动发起的一个 OPTIONS 请求,用于询问服务器是否允许实际请求。代码中无需手动编写。

简单请求 vs 非简单请求
类型条件是否触发预检
简单请求方法为 GET/HEAD/POST,且 Content-Type 为表单类型(application/x-www-form-urlencodedmultipart/form-datatext/plain),且无自定义头不触发
非简单请求不满足上述任一条件(如 PUT/DELETE 方法、application/json、携带 Authorization 头等)触发预检

application/x-www-form-urlencoded 是普通表单默认类型,multipart/form-data 用于带文件上传的表单,text/plain 为纯文本类型,这三种都属于传统表单格式;而 application/json 用于发送 JSON 格式数据,不属于传统表单类型,是后来 Ajax 常用格式,因此属于非简单请求,会触发预检

11. 总结

HTTP 定义了请求与响应的格式、方法、状态码、缓存规则。它本身无状态,因此引入 Cookie 和 JWT 维持用户状态。跨域问题由浏览器的同源策略引起,CORS 是标准的解决方案,其中预检请求用于保护非简单跨域请求的安全性。理解这些概念,就能处理跨域、缓存、安全、登录态管理等前端核心问题。