应为视频流资源(如.mp4、.webm)配置Cache-Control: public, immutable, max-age=31536000和Accept-Ranges: bytes,精准匹配视频路径或后缀,禁用压缩,显式缓存206响应,避免no-cache等错误设置。

视频流文件(如 MP4、WebM)在网页中常通过 <video> 标签加载,浏览器默认会对这些资源进行预加载(preload),但若 Nginx 未正确配置缓存策略,可能导致重复请求、带宽浪费或首帧延迟。关键在于:为视频流资源设置合适的 Cache-Control 响应头,既要支持字节范围请求(Accept-Ranges: bytes),又要允许客户端长期缓存,同时避免因强缓存导致内容更新不及时的问题。
明确视频流资源的匹配范围
不要对所有静态文件一概而论,只针对实际提供视频流的路径或后缀做精细化控制。常见做法是按文件扩展名或 location 路径区分:
- 匹配
.mp4、.webm、.m4v等二进制视频格式 - 若使用统一接口(如
/api/stream?id=xxx),需配合map指令或add_header在特定 location 中设置 - 避免作用于
/upload/或用户上传目录等可能频繁变更的路径
配置支持 Range 请求的缓存策略
视频预加载依赖 HTTP Range 请求(如 Range: bytes=0-1023)。若响应头中缺失 Accept-Ranges: bytes,或缓存策略与 Range 冲突(如设置了 Cache-Control: no-store),浏览器将无法分片加载,回退为完整下载,失去流式体验。
推荐 Nginx 配置片段:
location ~ \.(mp4|webm|m4v|ogg)$ {
add_header Accept-Ranges bytes;
add_header Cache-Control "public, immutable, max-age=31536000";
# 或更保守:max-age=2592000(30天),适用于内容稳定场景
expires 1y;
}说明:
– public 允许 CDN 和浏览器共同缓存;
– immutable 告诉浏览器:该资源内容不会在缓存有效期内改变(配合版本化文件名或指纹哈希时最有效);
– max-age=31536000 对应 1 年,适合静态视频资源;若内容会更新,建议用文件名哈希(如 demo-abc123.mp4)再配 long cache,而非缩短 max-age。
规避常见陷阱
以下配置看似合理,实则破坏视频流缓存行为:
-
add_header Cache-Control "no-cache";—— 强制每次验证,失去本地缓存意义,且可能干扰 Range 请求流程 - 未设置
Accept-Ranges或设为none—— 浏览器拒绝分片请求,预加载失效 - 在启用了 gzip/brotli 压缩的 location 中直接返回视频 —— 视频是二进制文件,不应压缩;务必确保
gzip off;或gzip_disable "msie6";等规则不误触视频路径 - 使用
proxy_cache但未配置proxy_cache_valid 206 1h;—— HTTP 206(Partial Content)响应默认不被缓存,需显式声明
验证与调试方法
部署后务必验证响应头是否生效:
- 用
curl -I https://yoursite.com/video.mp4查看Cache-Control和Accept-Ranges - 在 Chrome DevTools 的 Network 面板中播放视频,观察请求状态:首次为 200,后续 seek 操作应触发 206,且 Size 显示
from disk cache或from memory cache - 修改视频并重命名重新上传(保持旧链接 404),确认旧缓存仍可用 —— 这是
immutable + long max-age正确起效的表现
不复杂但容易忽略:Cache-Control 不是越“强”越好,而是要匹配视频内容的发布节奏和前端加载方式。用对了,预加载变顺滑;配错了,反而拖慢首帧。

















