知识与指南

下载总从头开始?断点续传、206 与 416 状态码解析

下载中断后又从头开始,先检查服务器是否接受指定字节范围,以及远端文件是否仍是同一版本。断点续传不是“把收到的数据直接拼上去”:206、200 和 416 的含义不同,代理开关也可能同时改变出口与访问结果。先用单独的小探测文件核对响应,再决定如何处理已有文件。

先读状态码,不要先删除半成品

HTTP 的 Range 请求用于索取选定范围。服务器可以忽略范围而返回完整内容;收到 206 时,还应核对 Content-Range 是否对应请求的位置。416 表示请求范围无法满足,不能直接当作下载完成。来源:RFC 9110 范围请求与状态码

最终响应 能说明什么 下一步
206 返回部分内容 核对范围、总长度和文件版本
200 返回完整内容 不要追加到原半成品
416 范围无法满足 比较本地长度、远端长度及版本
401、403 或登录页 当前访问未获得目标文件 先核对会话、权限或链接有效性

Accept-Ranges: bytes 是有用线索,但不能代替一次实际请求。即使得到 206,也不能跳过对资源身份的核对。

第一步:用独立文件探测一个字节

以下按 PowerShell 7.3 及以上默认的原生命令传参方式编写,以保留后续 ETag 参数内的双引号;使用旧版或 Legacy 模式时,应另行核对引号传递。来源:Microsoft 原生命令参数说明

先检查 curl.exe --version,并把示例地址换成自己有权限访问的真实下载地址;example.com/file.zip 不是本文提供的下载资源。

$downloadUrl = 'https://example.com/file.zip'
curl.exe -q --silent --show-error --location --max-redirs 3 --max-time 20 --max-filesize 1048576 --range 0-0 --header 'Accept-Encoding: identity' --dump-header range-headers.txt --output range-probe.bin "$downloadUrl"

命令请求第一个字节,把响应头和探测内容写到两个独立文件,执行前确认这些文件名没有重要内容。它不会把结果写进原来的下载半成品。-q 放在首项以忽略默认配置,示例也没有关闭证书校验。

范围限制可能被服务器忽略,所以额外限制时间及最大文件大小。文件大小未知时,下载途中触及阈值也会停止的行为需要 curl 8.4.0 或更新版本;旧版本不能把这个参数当作同等的流量上限。遇到大小限制错误时,也要查看已保存的响应头。来源:curl 参数手册

重定向可能留下多组响应头,要看最终文件响应,不能把中间跳转的 302 当成范围请求结果。确认 206 时,留意是否出现对应首字节的 Content-Range;实际格式与总长度以输出为准,本文不提供虚构响应成绩。

第二步:确认半成品属于哪一个版本

记录初次下载时保存的最终地址、文件长度、内容编码和强 ETag。仅仅文件名相同,不能证明源文件没有更新;现在查到的 ETag,也不能替代当初半成品对应的标识。

If-Range 可以把“版本仍匹配”作为范围请求条件;不匹配时服务器会忽略范围,改为返回完整表示。带 W/ 的弱 ETag 不能用在这个条件里。来源:RFC 9110 的 If-Range 定义

如果下载器自动解压了响应,或者访问地址指向动态生成的内容,也要检查本地字节与远端表示是否一致。没有可靠版本依据时,保留原文件,另存一份完整下载进行比较,比盲目追加更容易验证。

第三步:满足条件后再续传

curl 的 --continue-at - 会依据指定本地文件的现有长度确定续传偏移,适合继续同一资源的中断下载;它本身不会证明旧文件的身份。来源:everything curl 续传说明

下面会向指定的 .part 文件续写,先备份文件,并确认它与同一地址、同一版本、相同编码对应。强 ETag 占位内容须替换为初次下载时保存的真实值,保留必要的引号。

curl.exe -q --show-error --fail --location --max-redirs 3 --continue-at - --header 'Accept-Encoding: identity' --header 'If-Range: "此前保存的强ETag"' --output archive.zip.part "$downloadUrl"

这里没有再加 --range,因为它与 --continue-at 不能同时用于一次传输。若工具报告不支持续传,先保留错误,不要用 >> 把未知响应硬拼进文件。

416 可能与本地文件已经达到远端长度有关,也可能是资源变小、地址变化或偏移错误。应先看总长度与版本,再核对文件校验值,不能一看到 416 就宣布成功。

开关代理后结果不同,应该怎么比较?

保持地址、请求头、身份状态与文件版本一致,每次使用不同的探测输出文件。对比最终状态、重定向目标、Content-Range、ETag 和编码;不要让后一次测试覆盖前一次证据。

一次差异不足以认定代理改写了 Range。出口变化可能伴随不同的服务响应;登录状态或链接过期也可能让“下载”变成一个页面。若还没有确认终端确实使用了预期代理,可先按终端代理接入检查方法核对路径。

如果范围请求正常,但传输仍在中途停住,应把“是否支持续传”和“为什么连接中断”分开处理;后者可进一步参考大文件停滞与 MTU 检查。

结束前验证文件,而不是只看进度条

Get-FileHash -LiteralPath '.\archive.zip.part' -Algorithm SHA256

将结果与可信发布方针对同一版本、同一文件公布的 SHA256 比较。只计算出一个哈希值,并不代表已经验证成功;还要有独立可信的对照值。来源:Microsoft Get-FileHash 文档

记录项目 待填写内容
文件身份 最终地址、版本、原始 ETag、编码
本地状态 半成品字节数与备份位置
范围测试 200、206 或 416,及 Content-Range
访问路径 代理方式、测试时段、重定向差异
最终验证 发布方校验值、本地校验值、是否一致

本文命令是操作示例,未在读者设备执行。分享记录前遮住带签名的下载地址、Cookie 和账户令牌;排查范围请求通常不需要公开这些凭据。

资料核对日期:2026-10-15。

评论

搜索文章

正在加载搜索…