controlslist="nodownload"仅禁用原生下载按钮,无法阻止右键另存为;JS可通过preventDefault()隐藏右键菜单、动态加载音频、Blob播放等方式提高保存门槛,但无法彻底禁止。

controlslist="nodownload" 本身不阻止右键另存为
controlslist="nodownload" 只影响原生控件(比如播放器底部的下载按钮),浏览器根本不会因此禁用右键菜单或禁用 audio 元素的上下文菜单。右键 → “另存为音频” 这个选项由浏览器直接提供,和 controlslist 无关,也绕过所有 HTML 属性控制。
JS 无法真正阻止右键另存为,但能干扰常见触发路径
浏览器出于安全和用户体验考虑,不允许网页完全屏蔽用户保存已加载资源的能力。JS 能做的只是增加一点门槛,比如:
- 监听
contextmenu事件并调用e.preventDefault(),可隐藏右键菜单(但用户仍可通过地址栏、网络面板、媒体源查看器直接拿到 URL) - 避免使用明文可猜的音频路径(如
/audio/123.mp3),改用带短期签名的临时链接(如/audio?token=abc123&expires=1718…) - 服务端设置
Content-Disposition: attachment会适得其反——它反而会强制触发下载,应确保返回的是inline且Accept-Ranges: bytes
真正有效的组合策略(不是“阻止”,而是“提高获取成本”)
以下做法不能 100% 防止保存,但能过滤掉大部分随手右键的用户:
- 用
preload="none"+ JS 动态src设置,让初始 HTML 不暴露真实音频地址 - 对音频资源启用 CORS,并在 JS 中用
fetch()+arrayBuffer()+URL.createObjectURL()播放,此时原始 URL 不出现在网络面板的“媒体”标签页(但仍可在“全部”中搜到请求) - 服务端对 referer 或 token 做校验,直接拒绝无合法来源的音频请求(注意:referer 可伪造,仅作基础防护)
- 禁用右键菜单的同时,加一段提示:
document.addEventListener('contextmenu', e => { if (e.target.tagName === 'AUDIO') e.preventDefault(); });
别碰 oncontextmenu 行内属性或 event.returnValue = false
这些写法老旧且兼容性差;现代标准只认 e.preventDefault()。更重要的是:一旦你用 JS 把音频 blob 化再播放,<audio> 标签的 src 就是 blob:https://...,这时候右键菜单里“另存为”选项通常直接灰掉——不是因为你代码强,而是浏览器对 blob URL 本就不提供保存入口。这才是最接近“生效”的时刻。
立即学习“前端免费学习笔记(深入)”;



















