跳转至

HTTP 与 HTTPS

动机:让资源操作可互操作

Web 客户端和服务器可能由不同语言、系统和厂商实现。HTTP 规定了资源如何命名、请求如何表达、响应如何说明结果,使双方不需要共享内部代码。

URL https://www.example.com:443/docs/index.html?lang=zh#intro 可拆为:

部分 例子 作用
scheme https 选择访问协议与安全语义
host www.example.com 服务器名称,通常交给 DNS
port 443 目标服务端口,可省略默认值
path /docs/index.html 服务器上的资源标识
query lang=zh 传给服务器的参数
fragment intro 通常只由浏览器定位页面片段,不发送给服务器

最小完整例子

一个简化的 HTTP/1.1 请求:

GET /hello HTTP/1.1
Host: example.com
Accept: text/html
Connection: keep-alive

对应响应:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 18
Cache-Control: max-age=60

<h1>Hello!</h1>

起始行表达动作或结果,首部携带元数据,空行后是可选消息体。真实 HTTP/2、HTTP/3 使用二进制帧,不会在网络中原样出现上述文本,但方法、状态码和首部语义延续下来。

方法、状态码与幂等性

常见方法:

  • GET 获取资源,通常应是安全且幂等的。
  • HEAD 只取响应首部。
  • POST 提交数据,是否幂等取决于应用。
  • PUT 用给定表示创建或替换资源,设计上通常幂等。
  • DELETE 请求删除资源,重复执行应收敛到同一目标状态。

状态码按类别表达结果:2xx 成功,3xx 重定向,4xx 表示请求侧问题,5xx 表示服务器未能完成有效请求。幂等性很重要,因为超时后客户端可能不知道服务器是否已经执行操作。对支付接口盲目重试 POST 可能重复扣款,工程上常使用幂等键把重试识别为同一次业务操作。

HTTP 核心是无状态请求—响应协议:服务器不应仅凭“这是同一条 TCP 连接”推断用户身份。应用仍可以通过 Cookie 携带会话标识:

服务器响应 Set-Cookie: session=abc; Secure; HttpOnly; SameSite=Lax
浏览器后续请求 Cookie: session=abc

Cookie 带来登录与个性化,也引入泄漏、跨站请求和跟踪风险。Secure 限制经 HTTPS 发送,HttpOnly 限制脚本读取,SameSite 缓解部分跨站请求伪造;它们是互补措施,不是万能开关。

连接与版本演进

  • HTTP/1.0 常为每个对象建立连接,握手开销明显。
  • HTTP/1.1 默认持久连接,但同一连接上的响应队列会受到顺序影响。
  • HTTP/2 在一个 TCP 连接上用多个流复用请求,并压缩首部;TCP 丢包仍可能暂时阻塞同连接中的流。
  • HTTP/3 在 QUIC 之上运行,各流独立处理丢失,并把传输安全与连接建立更紧密地结合。

版本演进的动机不是改变 GET 的含义,而是降低握手、首部和队头阻塞成本。代价是实现、调试和中间设备兼容性更复杂。

缓存为何既快又难

缓存避免重复传输和服务器计算。服务器可用 Cache-Control 指定新鲜期,用 ETag 标记表示版本;缓存过期后客户端可以发送条件请求,若内容未变,服务器返回 304 Not Modified 而不重传主体。

缓存的代价是“一致性”。缓存键若遗漏语言、编码或认证上下文,可能把错误内容交给用户;敏感响应若错误标为公共缓存,还会造成数据泄漏。缓存策略必须结合资源是否可共享、允许陈旧多久和验证成本决定。

HTTPS 多了什么

HTTPS 是 HTTP 运行在受 TLS 保护的通道上。它主要提供:

  • 机密性:旁观者难以读取应用内容。
  • 完整性:传输中的篡改可被检测。
  • 服务器认证:客户端通过证书链和主机名验证对端身份。

HTTPS 不保证服务器业务可信,也不隐藏所有元数据。对手通常仍能观察连接两端 IP、数据量和时序;域名可见性取决于 DNS 与握手技术。TLS 细节见 TLS 与可信连接

亲手观察

curl -v https://example.com/
curl -I https://example.com/

前者可观察解析、连接、TLS、请求和响应,后者主要获取首部。诊断时先确认“是否解析成功、是否建立连接、是否完成 TLS、收到哪个 HTTP 状态”,比笼统地说“网站打不开”更可行动。

自测

HTTP/2 为什么没有彻底消除队头阻塞?

它消除了 HTTP/1.1 应用层响应必须排队的问题,但多个流仍共享一个 TCP 字节流。底层某个 TCP 段丢失时,TCP 必须先恢复有序字节,其他流也会暂时等待。