try_files 不处理断点续传,仅按序检查文件存在性并内部跳转;断点续传生效取决于 nginx 是否原生响应 range 请求(206),需确保其最终指向真实静态文件、禁用干扰配置(如 gzip/range 冲突、rewrite、add_header accept-ranges "none"),代理场景应改用 proxy_pass 显式透传 range 头。

try_files 本身不参与断点续传逻辑,它也不处理 Range 请求或 206 响应。它的作用是按顺序检查文件是否存在,并决定内部跳转路径。大文件下载的断点续传能否生效,取决于 Nginx 是否正确响应 HTTP Range 头(返回 206 Partial Content),而 try_files 只是帮你把请求“导向”到那个可被 Range 处理的静态文件上——前提是目标文件真实存在、权限正确、且未被其他配置阻断。
确保 try_files 最终指向的是真实可读的静态文件
断点续传依赖底层文件可被 Nginx 直接读取并分片响应。如果 try_files 把请求错误地重写到了一个不存在的路径、PHP 脚本(如 /index.php)或代理后端,那 Range 就彻底失效了——因为 PHP 或上游服务未必支持或透传 Range。
- ✅ 推荐写法(直出静态文件):
location /dl {
alias /data/downloads/;
try_files $uri =404;
}
这样既校验文件是否存在,又让 Nginx 原生处理 Range;$uri 对应的就是磁盘上的真实文件。 - ❌ 避免写法(误导向脚本):
try_files $uri /index.php?$args;
哪怕文件存在,也会被强制交给 PHP,失去原生 Range 支持。
不要在 try_files 后加 gzip 或 rewrite 干扰 Range 流程
某些常见配置会悄悄破坏断点续传:
- gzip on 且未禁用 range:对大文件启用 gzip 会导致 Nginx 无法返回 Content-Range,必须加 gzip_disable "range";
- rewrite 指令介入:rewrite 会重置请求上下文,可能丢弃原始 Range 头;若必须 rewrite,请确保它发生在 try_files 之前,且不改变最终文件路径语义。
- add_header Accept-Ranges "none";:显式禁用,直接关闭断点续传能力,务必删除。
代理场景下,try_files 不适用,需改用 proxy_pass + 显式透传
如果你用 try_files 想“先查本地缓存文件,没有再 proxy_pass”,这种混合模式在大文件下载中风险很高:Nginx 不会在 proxy_pass 时自动继承 $uri 的 Range 行为,必须手动透传头并控制缓存。
- 正确做法是放弃 try_files,改用条件判断(如 if + -f)或专用缓存策略:
location /dl {
if (-f $request_filename) {
add_header Accept-Ranges bytes;
break;
}
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_pass http://backend;
} - 更稳妥的是用 proxy_cache + proxy_cache_bypass $http_range;,避免重复判断文件存在性。
验证是否真正生效:用 curl 看响应状态和头
别只看文件能不能下载,要确认断点续传通道已通:
- 执行:
curl -I -H "Range: bytes=0-1023" https://yoursite/dl/big.zip - ✅ 成功表现:
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Range: bytes 0-1023/123456789 - ❌ 失败表现:
HTTP/1.1 200 OK(说明被重定向或脚本接管)
或缺少 Accept-Ranges / Content-Range 头











