chrome 95+已废弃controlslist="nodownload",唯一可靠方案是弃用原生控件并自定义ui,配合服务端鉴权与响应头控制才能有效限制下载。

controlslist="nodownload" 在 Chrome 里失效怎么办
Chrome 95+ 已彻底忽略 controlslist="nodownload",哪怕写了也照常显示下载按钮。这不是你代码写错,是浏览器主动废弃了这个非标准行为——W3C 从未将其纳入规范,Chrome 团队明确表示“不打算支持下载控制”。
想隐藏下载按钮,唯一可靠方式是弃用原生控件,自己用 JS + <video></video> 的 API 实现自定义 UI:
- 移除
controls属性,避免原生控件干扰 - 用
video.download属性判断资源是否允许下载(仅当响应头含Content-Disposition: attachment或同源且未被 CORS 阻断时才有效) - 对跨域视频,
video.src指向 Blob URL 而非直接链接,可绕过部分下载限制(但无法阻止用户另存为)
用 JavaScript 禁用右键保存和拖拽下载的实操点
原生 controlslist 不起作用后,能做的其实是“降低普通用户下载意愿”,而非真正禁止。重点防的是右键菜单和拖拽行为:
- 监听
contextmenu事件并e.preventDefault(),能屏蔽右键菜单(但开发者工具里仍可拿到地址) - 对
<video></video>绑定dragstart并阻止,默认拖拽到桌面会生成 .webm 文件,阻止后无反应 - 注意:Safari 对
dragstart阻止不敏感,需额外加-webkit-user-drag: none样式 - 别用
onselectstart或user-select: none,它们对视频播放器本身无效
服务端配合才能真正禁下载:关键响应头设置
前端所有手段都只是障眼法。真要限制下载,必须从服务端切断直接访问媒体文件的能力:
- 返回视频时,HTTP 响应头中**不要加**
Accept-Ranges: bytes和Content-Range,否则curl -r或 IDM 仍能分段拉取 - 用一次性 token 签名 URL(如
/video/abc123.mp4?token=xyz&exp=171…),服务端校验通过才输出文件流,过期即 403 - 对 HLS 流,确保
.m3u8和所有.ts分片都走鉴权,且分片 URL 动态生成、有效期短于 30 秒 - 避免在 HTML 里明文暴露真实视频地址,比如别把
src="https://cdn.example.com/xxx.mp4"写死在标签里
移动端 Safari 的特殊处理:download 属性完全无效
iOS/iPadOS 的 Safari 不支持 download 属性,也不响应 controlslist,甚至连 video.href 都不可读。这意味着:
- 你在
<a download="xxx"></a>里套<video></video>,点击后只会跳转播放页,不会下载 - 用
fetch+Blob+URL.createObjectURL方案,在 iOS 上会触发新页面播放,而非下载 - 唯一可行路径是后端提供独立下载接口(如 POST
/api/download?id=xxx),返回带Content-Disposition: attachment的响应,且该接口需登录态校验
说到底,controlslist 从来就不是下载控制方案,它只是个被浏览器随意实现又随意废弃的提示性属性。真要管住下载,得从前端交互遮蔽、服务端鉴权、CDN 策略三层同时动手,缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











