Nginx实现分片状态码无损返回的关键是透传206响应及Content-Range、Accept-Ranges等头,需确保源站正确返回206、关闭proxy_redirect、禁用error_page 416=200、启用HTTP/1.1、强制透传关键响应头,并在使用slice模块时为206单独配置cache_valid。

Nginx 本身不生成或修改 HTTP 状态码,它只是透传、转发或根据逻辑返回。所谓“分片状态码无损返回”,核心是指:当客户端请求 Range(如拖动视频进度条),后端正确返回 206 Partial Content 且附带完整、合法的 Content-Range 和 Accept-Ranges: bytes 头时,Nginx 必须原样透传这些响应头和状态码,不降级为 200,也不丢弃关键字段。
要达成这一点,配置重点不在“开启某个开关”,而在于避免默认行为干扰 + 显式补全必要协议支持。
✅ 确保后端真实返回 206 并带标准 Range 头
这是前提,Nginx 无法凭空造出 206:
- 源站(如静态文件服务、OSS、CDN 回源目标)必须:
- 响应头含
Accept-Ranges: bytes - 对
Range: bytes=0-1048575这类请求,返回状态码206,且头中含Content-Range: bytes 0-1048575/10485760
- 响应头含
- 可用
curl -I -H "Range: bytes=0-1023" https://origin.example.com/video.mp4验证
若源站返回 200 或无 Accept-Ranges,Nginx 即使配得再好,也只会转发 200 或报 416。
✅ 关闭可能降级 206 的默认代理行为
Nginx 默认对某些响应会“优化”处理,反而破坏分片语义:
-
禁用
proxy_redirect default;或模糊重写
若配置了proxy_redirect且匹配到 206 响应,可能误改Location或状态码(虽少见,但自定义规则下存在风险)。建议显式关闭:proxy_redirect off;
不要用
error_page 416 =200 /fallback;类兜底
416 是 Range 请求无效时的标准响应,强行转成 200 会破坏播放器逻辑(如 video.js、hls.js 会直接失败)。避免
add_header覆盖或冲突
不要手动加Content-Range或Accept-Ranges,除非你完全控制后端且确认缺失——否则可能与真实响应冲突,导致浏览器拒绝解析。
✅ 显式启用 HTTP/1.1 并清理干扰连接头
206 是 HTTP/1.1 规范特性,且依赖 Connection 头清理以保障连接复用不中断:
proxy_http_version 1.1; proxy_set_header Connection '';
- 缺少这两行,某些中间代理或旧版客户端可能将
206当作不完整响应处理; -
Connection: keep-alive若被后端或 Nginx 自动注入,可能在复用连接时引发Content-Range解析错乱。
✅ 强制透传关键响应头(推荐)
Nginx 默认不透传所有响应头,尤其自定义或非标准头。对视频分片,以下三者必须透传:
proxy_pass_request_headers on; # 确保原始请求头(如 Range)能发给后端(虽非返回阶段,但影响能否触发 206) proxy_hide_header X-Powered-By; # 可选:隐藏无关头 # 关键:强制透传 Range 相关响应头 proxy_pass_header Content-Range; proxy_pass_header Accept-Ranges; proxy_pass_header ETag;
⚠️ 注意:
proxy_pass_header是 透传,不是 添加;它告诉 Nginx “即使你本来想藏,也给我放行”。
✅ 配合 slice 模块时的特别注意(如需分片回源)
如果你同时启用了 ngx_http_slice_module(用于大文件边缘分片拉取),则必须:
- 保持
proxy_buffering on;(关闭会禁用 slice) -
proxy_cache_key中包含$slice_range,否则不同分片缓存 key 冲突,可能导致某次返回200覆盖掉本该是206的缓存项 -
proxy_cache_valid必须同时声明:proxy_cache_valid 200 1h; proxy_cache_valid 206 24h; # 206 必须单独设有效期,否则不进缓存
否则,Nginx 可能缓存住一个 200 响应,后续相同 URI 的 Range 请求被错误地从缓存返回 200(内容完整但无 Content-Range),播放器直接报错。
不复杂但容易忽略。











