Nginx支持大文件断点续传需三步:一用proxy_cache_key "$uri|$http_range"区分Range缓存;二配proxy_cache_valid 200 206 1h显式缓存206响应;三禁用proxy_cache_bypass $http_range等干扰策略,并添加Vary: Range头。

要让 Nginx 缓存真正支持大文件断点续传,关键不是“缓存整个文件”,而是让每个 Range 请求都能命中对应字节段的缓存条目,避免反复回源打爆后端。这需要缓存键区分范围、明确允许缓存 206 响应、并绕过干扰策略。
缓存键必须包含 Range 信息
默认缓存 key(如 $uri $args)完全忽略 Range 头,所有分片请求都指向同一个缓存项,结果要么返回错误字节,要么降级为全量 200 响应,导致重复拉取。
- 推荐写法:
proxy_cache_key "$uri|$http_range";——简洁可靠,空值(全量请求)和非空值(如bytes=0-1023)自动区分 - 若已启用
slice模块,可用$slice_range,但需确保全局开启且配置一致 - URL 中含随机参数(如
?t=1716825783)时,先用map提取纯净路径再拼接,防止缓存碎片化
显式允许缓存 206 响应
Nginx 默认不缓存 206 响应,即使 key 正确也会穿透。必须主动声明有效状态码和过期时间:
-
proxy_cache_valid 200 206 1h;——同时覆盖完整响应与分片响应,1 小时是稳妥起点 - 对长期不变的大文件(如安装包、课程视频),可设为
24h或更长;对更新频繁的资源,缩短至10–30m - 避免写
206 0s这类无效配置,它等同于不缓存
防止 Range 请求被缓存策略误伤
某些通用缓存规则会强制校验或跳过缓存,导致 Range 请求无法复用已有缓存:
-
proxy_cache_bypass $http_range;——有 Range 头就跳过缓存查找,直接进入代理流程(配合上面的 cache_key 才有意义) -
proxy_no_cache $http_range;——有 Range 头就不存响应到缓存(适用于只读缓存、不写缓存的场景) - 更常用组合是两者都启用,即:有 Range 就不查也不存,靠精准 key + valid 实现复用
补充协同响应头,提升链路兼容性
仅服务端缓存到位还不够,客户端和中间 CDN 需知道该资源支持分片、且不同 Range 应视为不同实体:
-
add_header Vary "Origin, Range";——明确告知缓存系统:响应内容随 Origin 和 Range 变化,不可混用 - 确认未设置
add_header Accept-Ranges "none";等禁用头 - 若使用反向代理,务必透传原始请求头:
proxy_set_header Range $http_range;和proxy_set_header If-Range $http_if_range;


















