controlslist="nodownload" 仅隐藏Chrome/Edge原生下载按钮,非安全机制;Firefox忽略、Safari支持弱,右键另存为、DevTools抓流等均无效,需配合controls属性、Content-Disposition: inline、禁用右键等多重手段提升门槛。

controlslist="nodownload" 为什么不能阻止下载
它只是告诉 Chrome/Edge 隐藏原生控件里的下载按钮,不是安全机制。Firefox 完全忽略,Safari 支持极弱;右键“另存为”、DevTools → Network → 找 .mp4 或 .ts 请求、甚至长按视频唤起系统菜单,都不受这个属性影响。写成 controlslist="no-download" 或漏掉 controls 属性,它就直接失效。
真正起效的组合写法
必须同时满足以下条件,才能让 UI 层下载入口尽可能消失:
-
controls和controlslist="nodownload"必须共存,缺一不可 - 值之间用空格分隔,不能加逗号:
controlslist="nodownload nofullscreen"✅,controlslist="nodownload, nofullscreen"❌ - 服务端响应头加上
Content-Disposition: inline,避免浏览器误判为可下载资源 - 配合
oncontextmenu="return false"放在最外层<div>或<body>上,且确保没有pointer-events: none阻断事件冒泡
移除 src + Blob URL 是更难绕过的做法
当你要提高普通用户操作门槛(不是追求绝对安全),可以放弃原生控件:
- 设
controls="false",彻底隐藏所有原生按钮 - 用
URL.createObjectURL(new Blob([arrayBuffer], {type: 'video/mp4'}))动态生成src,真实地址不出现在 HTML 源码里 - 此时右键菜单中“另存为”通常灰掉,因为
src是blob:开头的内存地址 - 注意:Blob URL 页面刷新即失效;iOS Safari 对
MediaSource支持有限,需 fallback 到 HLS
真正难防的是网络请求本身
只要视频能播放,就必然经过解码和缓存。用户打开 DevTools → Network → Filter media,点开任意一个 206 响应,右键 Copy link,就能拿到完整文件。前端 JS 拦截 fetch 或 XMLHttpRequest 对媒体请求无效——浏览器媒体栈绕过 JS 网络层。需要 DRM(如 Widevine)+ 加密打包 + 许可证服务器,才可能真正限制复制。
立即学习“前端免费学习笔记(深入)”;



















