HTTP Range 请求是什么?前端下载和媒体播放如何利用它?
简化版
HTTP Range 请求允许客户端只请求资源的一部分,例如 Range: bytes=0-1023。服务端支持时会返回 206 Partial Content 和 Content-Range。它常用于视频拖动播放、断点下载、大文件预览和分段加载。前端要注意服务端是否支持 Accept-Ranges、跨域是否暴露响应头、分片合并、缓存和错误恢复。
详细版
Range 请求的关键响应状态码是 206。
| Header/状态 | 含义 |
|---|---|
Range | 客户端请求字节范围 |
206 Partial Content | 服务端返回部分内容 |
Content-Range | 返回范围和总大小 |
Accept-Ranges | 服务端声明支持范围请求 |
GET /video.mp4 HTTP/1.1
Range: bytes=1048576-2097151
Range 是“只拿一段资源”,不是前端自己把完整响应截断。
完整版教学
一、为什么需要 Range
大文件不适合每次完整下载。用户看视频时拖到中间,如果必须从头下载,体验会很差。
Range 允许浏览器或前端请求指定字节段,从而支持拖动播放、断点续传和并行分段下载。
二、基本请求和响应
客户端发送:
Range: bytes=0-1023
服务端返回:
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/10000
如果服务端不支持,可能返回 200 和完整内容。
三、前端能不能直接设置 Range
Fetch 可以设置 Range header,但跨域时会涉及 CORS。服务端需要允许请求头,并暴露响应头。
Access-Control-Allow-Headers: Range
Access-Control-Expose-Headers: Content-Range, Accept-Ranges
否则前端可能拿不到范围信息。
四、媒体播放场景
视频和音频标签通常由浏览器自动发 Range 请求。服务端如果支持 Range,用户拖动进度条时浏览器可以请求目标位置附近的数据。
<video src="/movie.mp4" controls></video>
很多媒体播放问题其实是服务端没有正确支持 206。
五、断点下载场景
前端可以记录已下载字节,失败后从断点继续请求后续范围。最终把多个 Blob 合并。
| 步骤 | 说明 |
|---|---|
| 获取总大小 | HEAD 或 Content-Range |
| 分段请求 | 多个 Range |
| 校验顺序 | 按字节范围排序 |
| 合并 Blob | 生成下载链接 |
六、缓存和 CDN
CDN 是否支持 Range 会影响大文件体验。某些 CDN 对 Range 回源和缓存有特殊配置。
如果 Range 配置不当,可能导致每次拖动都回源,或者缓存碎片过多。
七、常见误区与追问
- 误区:Range 是前端下载完整文件后截取。 Range 是请求头告诉服务端只返回指定字节。
- 误区:状态码 200 和 206 没区别。 206 表示部分内容,200 通常是完整响应。
- 误区:video 拖动慢一定是前端播放器问题。 服务端 Range、CDN 和编码格式都可能影响。
- 追问:如何判断服务端支持 Range? 看
Accept-Ranges、请求 Range 后是否返回 206 和 Content-Range。 - 追问:跨域读取 Content-Range 要注意什么? 服务端要在
Access-Control-Expose-Headers暴露它。 - 追问:Range 和分片上传一样吗? Range 用于下载部分资源,分片上传用于上传部分文件。
八、加强记忆
Range 记成“按字节点菜”。客户端点一段,服务端回 206;视频拖动、断点下载和大文件预览都靠它,但服务端、CDN、CORS 头要配合。