controlslist="nodownload"不起作用是因为它仅为UI提示而非强制策略,仅Chrome/Edge部分支持且需同源或blob URL才生效,Firefox/Safari完全忽略,无法阻止右键另存、DevTools抓包等下载方式。

controlslist="nodownload" 为什么不起作用
直接写 controlslist="nodownload" 在大部分浏览器里确实无效——这不是你代码写错了,而是该属性只在特定条件下生效。Chrome 和 Edge 从 76 版本起支持 controlslist,但仅当视频是同源(same-origin)或通过 blob: / data: URL 加载时才真正禁用下载按钮;跨域视频(比如 CDN 上的 MP4)即使写了也会被忽略。
- 检查控制台是否报
Unsafe attempt to retrieve video URL from cross-origin frame类错误,这是跨域导致的典型失效原因 - 确保
<video>没有同时设置crossorigin属性——它会强制触发 CORS 请求,反而让controlslist失效 - Firefox 完全不支持
controlslist,Safari 也不支持,所以别指望它跨浏览器生效
替代方案:用 CSS 隐藏下载按钮(仅限 Chrome/Edge)
CSS 方案不是“禁用”,而是视觉隐藏,但实操中更可靠。Chrome/Edge 的原生控件里下载按钮是个独立伪元素,可用以下样式压制:
video::-webkit-media-controls-overlay-panel {
display: none !important;
}
video::-webkit-media-controls-enclosure {
padding-bottom: 0 !important;
}
注意这仅影响 WebKit/Blink 内核,且必须配合 controls 属性使用;如果去掉 controls,整个控件条都没了,用户连播放都困难。
- 不要用
display: none直接隐藏<video>的controls,那样会移除所有控件 - 部分新版 Chrome 对伪元素选择器做了限制,若失效可尝试加
!important并确认 CSS 加载顺序 - 这个方案无法阻止右键另存为或开发者工具里提取 src,纯属 UI 层遮蔽
真正防下载只能靠服务端配合
前端任何手段都无法阻止用户拿到视频数据——只要浏览器能解码播放,就说明数据已到达客户端。想降低下载门槛,得从源头控制:
立即学习“前端免费学习笔记(深入)”;
- 用 HLS 或 DASH 分片 + token 鉴权,每次请求带时效签名,让直链失效
- 服务端响应头加
X-Content-Type-Options: nosniff和Content-Disposition: attachment; filename=xxx不要暴露,否则反而诱导下载 - 避免提供完整 MP4 的公开 URL;改用后端代理接口,对 Referer、User-Agent 做校验
单纯依赖 controlslist 或 CSS 隐藏,只是把“下载按钮”藏起来,而不是把“下载能力”关掉。



















