100 的定位
100 Continue 是一个「中间响应」:客户端发出带 Expect: 100-continue 的请求头后暂停发送请求体,等服务器回 100 再上传;若服务器直接回 4xx/5xx,客户端就不必白白上传。它是 HTTP/1.1 引入的机制(RFC 9110 §15.2.1),HTTP/2 与 HTTP/3 保留同样语义,只是换成 :status 100 的 HEADERS 帧。
基本信息
| 名称 | 100 Continue |
|---|---|
| 类型 | 1xx 中间响应(不是最终响应) |
| 规范 | RFC 9110 §15.2.1;Expect 见 §10.1.1 |
| 触发条件 | 请求头 Expect: 100-continue |
| HTTP/2、3 | 服务器以 HEADERS 帧发送 :status 100 |
典型使用场景
- 大文件上传前先让服务器校验:路径不存在、配额不足、类型不允许时直接拒绝,省掉整段上传
- 网关或对象存储先验身份再收正文:token 无效就不必收几百 MB 数据
- 弱网移动端上传:一次往返换取「不白传」的机会
- 排障与压测:观察 100 是否出现,判断链路中的代理有没有吞掉 Expect
交互时序
交互时序
客户端: POST /upload HTTP/1.1
Expect: 100-continue
服务器: HTTP/1.1 100 Continue
客户端: (开始发送请求体)
服务器: HTTP/1.1 200 OK
# 若校验不通过,服务器可直接回 4xx/5xx,客户端随即丢弃请求体三方行为对照
| 角色 | 校验通过 | 校验不通过 |
|---|---|---|
| 客户端 | 收到 100 后发送请求体 | 收到最终 4xx/5xx,不发请求体 |
| 服务器 | 先回 100,再读正文 | 跳过 100,直接回最终状态码 |
| 中间代理 | 转发 100,或按自身策略缓冲 | 不支持时可能直接放行正文,预检失效 |
客户端等约一秒仍未收到 100 时,RFC 9110 的实现建议是仍可继续发送请求体,避免死等;服务器也可以完全不发 100 直接给最终响应。
和直接上传的差别
不加 Expect 时,客户端会先把整个请求体推给服务器,服务器读到一半才发现配额不足或路径非法,带宽已经花掉;加了 Expect 则把「是否接受」的判断提前到一次极小的往返上。代价是多一个往返,以及在部分代理上被吞掉的不确定性,所以只有体积较大的上传才划算。
排障观察点
| 现象 | 可能原因 | 确认方式 |
|---|---|---|
| 没看到 100 就直接失败 | 服务器校验未通过,属正常路径 | 抓包看服务器是否跳过 100 直接给最终状态码 |
| 上传长时间卡住 | 服务器既未回 100 也未回最终响应 | 两端同时抓包,看 100 是否真的发出 |
| 经代理后预检失效 | 中间设备吞掉 Expect 或直接转发正文 | 同一脚本分别直连与经代理各跑一次对比 |
| 很久之后才收到 100 | 服务端校验逻辑本身很慢 | 比较 100 与最终响应之间的时间差 |
部分老旧代理与 WAF 对 1xx 的处理不完整:既可能不发 100,也不保证请求体被正确转发。上线前用同一份上传脚本分别直连与经代理各跑一次,比对结果。