HTTP / HTTPS(应用层协议)

1. 定义

HTTP (HyperText Transfer Protocol,超文本传输协议) 是 Web 的应用层协议,规定了客户端(浏览器)和服务器之间怎么请求、怎么响应——用什么格式发、有哪些方法、返回什么状态码。它跑在传输层 TCP 之上(HTTP/3 例外,跑在 UDP/QUIC 上)。

HTTPS = HTTP + TLS 加密。就是在 HTTP 和 TCP 之间加了一层 TLS,把明文传输变成加密传输。

一句话概括:HTTP 是浏览器和服务器之间的”对话规则”——一问一答、无状态、纯文本格式,简单到人都能读懂。

类比:HTTP 像点餐的标准话术。顾客(客户端)说”我要一份 /menu”(请求),后厨(服务器)回”好的,这是你的菜 200 OK”(响应)。规矩定死了怎么问怎么答,双方才能配合。HTTPS 就是把这段对话装进保密信封,中间传菜的人看不到内容。

2. HTTP 的三个核心特点

特点含义带来的影响
请求-响应客户端发起,服务器回应,永远一问一答服务器不能主动推送(要推送得用 WebSocket/SSE)
无状态 (stateless)每个请求相互独立,服务器默认不记得你”记住登录”要靠 Cookie/Session/Token 补
纯文本 (HTTP/1.x)报文是人类可读的文本易调试,但体积大、效率低(HTTP/2 起改二进制)

无状态是最重要的一点,它解释了 Web 开发一大堆机制的存在理由——见第 7 节会话保持,也呼应 server.md 第 9 节。

3. 报文格式(一问一答长什么样)

请求报文:

GET /index.html HTTP/1.1         ← 请求行:方法 + 路径 + 协议版本
Host: example.com                ← 请求头(headers):一堆 key: value
User-Agent: Mozilla/5.0
Accept: text/html
Cookie: sessionId=abc123
                                 ← 空行:分隔头部和主体
(GET 通常无主体;POST 的表单/JSON 放这里)

响应报文:

HTTP/1.1 200 OK                  ← 状态行:协议 + 状态码 + 描述
Content-Type: text/html; charset=utf-8   ← 响应头
Content-Length: 1234
Set-Cookie: sessionId=abc123     ← 服务器给浏览器"发身份牌"
                                 ← 空行
<html>...</html>                 ← 响应主体:真正的内容

可以用 curl -v https://example.com 亲眼看到这些报文。

4. 请求方法 (Method)

方法语义幂等?典型用途
GET获取资源读取数据,参数放 URL
POST提交数据新建资源、提交表单,数据放主体
PUT整体替换/创建更新整个资源
PATCH局部更新只改部分字段
DELETE删除资源删除
HEAD只要响应头不要主体检查资源是否存在/是否更新
OPTIONS询问支持哪些方法CORS 预检

幂等 (idempotent):同样的请求发一次和发多次,对服务器的效果一样。GET/PUT/DELETE 幂等(删一次和删两次结果都是”没了”);POST 不幂等(提交两次可能下两个订单)——所以刷新提交页面浏览器会警告”是否重新提交表单”。

5. 状态码 (Status Code)

含义常见
1xx信息,处理中101 切换协议(升级 WebSocket)
2xx成功200 OK、201 Created、204 No Content
3xx重定向301 永久跳转、302 临时、304 命中缓存不用重传
4xx客户端400 格式错、401 未认证、403 无权限、404 找不到、429 请求太频繁
5xx服务器500 内部错误、502 网关错误、503 不可用、504 网关超时

记法:4xx 你(客户端)的锅,5xx 我(服务器)的锅。 排错先看状态码定位方向。401(没登录)和 403(登录了但没权限)容易混:401=你是谁不知道,403=知道你是谁但不让你进。

6. 关键请求头/响应头(高频)

方向作用
Host请求访问哪个域名(一台服务器靠它区分多个网站)
Content-Type双向主体是什么格式:application/jsontext/htmlmultipart/form-data
Content-Length双向主体字节数
Authorization请求携带认证信息,如 Bearer <token>
Cookie / Set-Cookie请求/响应会话保持(见第 7 节)
Cache-Control双向缓存策略:no-cachemax-age=3600
User-Agent请求客户端标识(浏览器/爬虫类型)
Location响应配合 3xx,告诉浏览器跳转到哪

7. 无状态怎么”记住你”:Cookie / Session / Token

HTTP 无状态,服务器认人靠这套(详见 server.md 第 9 节):

首次登录:
  客户端 ──── POST /login (账号密码) ────▶ 服务器
  客户端 ◀── 200 + Set-Cookie: id=abc ──── 服务器(发身份牌)

后续请求:
  客户端 ──── GET /profile  Cookie: id=abc ────▶ 服务器(每次自动带上身份牌)
                                                 服务器凭 id 认出"这是刚才登录的人"
  • Cookie:浏览器自动保存并每次带上的小数据。
  • Session:状态存在服务器端,Cookie 里只放个 sessionId 当钥匙。→ 多机部署时 Session 要集中存(如 Redis)。
  • Token (JWT):状态签名后交客户端保管,服务器不用存,天然适合分布式。

8. HTTPS:HTTP 怎么变安全

HTTP 明文传输,中间任何节点都能看/改。HTTPS 在 TCP 和 HTTP 之间插一层 TLS

应用层   HTTP
   │
安全层   TLS   ← HTTPS 多出来的这层:加密 + 身份验证 + 完整性
   │
传输层   TCP

TLS 解决三件事:

  • 加密 (Confidentiality):内容被窃听也看不懂。
  • 身份验证 (Authentication):靠证书确认”对方真是 example.com”,不是钓鱼站冒充。
  • 完整性 (Integrity):内容被中途篡改能发现。

TLS 握手(简化):非对称加密协商出一个对称密钥,之后用对称加密传数据(对称快,非对称安全但慢,取两者之长)。

客户端 ─ 我支持这些加密套件 ─▶ 服务器
客户端 ◀─ 选这个套件 + 我的证书(含公钥) ─ 服务器
客户端 ── 用公钥加密一个随机数发过去 ──▶ 服务器(只有服务器私钥能解)
双方由此算出同一把对称密钥 ── 之后全用它加密通信

证书由受信任的 **CA(证书颁发机构)**签发,浏览器内置了信任的 CA 列表。证书过期/自签/域名不符,浏览器就报”不安全”。Let’s Encrypt 提供免费证书。

9. HTTP 版本演进(为什么越来越快)

版本底层关键改进解决的问题
HTTP/1.0TCP每个请求新建一个连接
HTTP/1.1TCP长连接 (keep-alive) 复用、管线化省掉反复握手,但仍有队头阻塞
HTTP/2TCP二进制分帧、多路复用、头部压缩、服务器推送一个连接并发多请求,解决 HTTP 层队头阻塞
HTTP/3UDP/QUIC换到 QUIC解决 TCP 层队头阻塞(丢一个包不再卡住所有流),握手更快

队头阻塞 (Head-of-Line Blocking) 是这条演进线的主线:HTTP/1.1 一个连接里请求得排队 → HTTP/2 在应用层用多路复用解决,但底层 TCP 丢包仍会卡住整条连接 → HTTP/3 干脆换 UDP,让各个流互不影响。呼应 tcp-udp.md 第 7 节”为什么 HTTP/3 从 TCP 换回 UDP”。

10. 常见坑 / 误区

  • ❌ “HTTPS 只是加密” → 不只,还有身份验证(防钓鱼)和完整性(防篡改)
  • ❌ “有了 HTTPS 就绝对安全” → 只保护传输链路;服务器被黑、XSS、弱密码等它管不了
  • ❌ “GET 和 POST 只是参数位置不同” → 语义也不同:GET 幂等且可缓存、参数在 URL(有长度限制、会被日志记录,别放敏感信息);POST 不幂等、数据在主体
  • ❌ “GET 请求不会改数据所以安全” → 语义上不该改,但如果后端写成 GET 也能改数据,就会被 CSRF 等利用;要遵守方法语义
  • ❌ “404 是服务器出错了” → 404 是 4xx,属客户端错(路径不存在);服务器崩了是 5xx
  • ❌ “Cookie 存在服务器上” → Cookie 存在浏览器,Session 才存服务器;Cookie 里通常只放 sessionId
  • ❌ “HTTP/2 就不用管 TCP 队头阻塞了” → HTTP/2 只解决了应用层的,TCP 层的要靠 HTTP/3(QUIC) 才解决
  • ❌ “把 token/密码放 URL 里” → URL 会被浏览器历史、服务器日志、Referer 泄露,敏感信息放主体或 Authorization 头

11. 延伸阅读 / 关联概念

  • TCP / UDP — HTTP 的传输层底座,理解队头阻塞的关键;见 tcp-udp.md
  • Socket — HTTP 服务器底层用 socket 收发;见 socket.md
  • 服务器原理 — 请求-响应、状态码、会话保持的宿主;见 server.md
  • 静态 vs 动态网页 — 服务器如何生成 HTTP 响应内容;见 ../web/static-vs-dynamic-pages.md
  • DNS 解析绑定 — 发 HTTP 请求前先解析域名;见 dns-binding.md
  • WebSocket — 在 HTTP 之上升级成的全双工长连接,解决”服务器不能主动推”的问题
  • TLS / 证书 / CA — HTTPS 安全的基础
  • CORS — 跨域资源共享,OPTIONS 预检的由来
  • HTTP 方法与 Fetch API — 怎么用 Fetch/curl 真正发出这些动词(实践层);见 http_methods_fetch.md