video标签无法防投屏,因HTML5无禁投屏属性;真正有效的是服务端鉴权、CORS限制、Referer校验及签名URL,前端措施均无效。

video标签本身无法防投屏,别在前端加“禁投屏”属性
HTML5 <video> 标签没有 disable-cast、no-casting 或任何类似属性。浏览器不提供前端可控的投屏开关——所谓“防投屏”,本质是阻止视频被外部设备拉取或转播,而这个动作发生在协议层或服务端,不是 DOM 层能拦截的。
常见误解包括:给 <video> 加 controlslist="nodownload noremoteplayback",其中 noremoteplayback 确实能隐藏 Chrome 的 Cast 按钮(仅限桌面),但它只影响 UI,不影响底层能力;用户仍可手动打开地址栏输入 chrome://cast 或用系统级投屏工具捕获整个窗口。
真正起作用的只有两点:限制视频资源的可访问性 + 阻断标准投屏协议发现路径。
用 CORS + Referer + Token 三重策略阻断跨站播放
跨站播放(比如别人把你的 src 地址贴到自己页面里直接播)能成功,说明视频文件被当作公开静态资源暴露了。防住它的核心是让每次请求都必须通过服务端鉴权,且校验上下文。
立即学习“前端免费学习笔记(深入)”;
-
Access-Control-Allow-Origin必须指定具体域名(如https://your-site.com),不能设为*;否则任何站点都能带crossorigin="anonymous"加载 - 后端对每个视频请求检查
Referer头,非白名单域名直接返回403;注意移动端 WebView 可能清空 Referer,需配合其他手段 - 所有
<source src="/video/123">指向的 URL 必须是带签名的临时地址(如/api/video/123?token=abc&exp=1729400000),服务端验证签名和过期时间后才流式返回视频数据
关键点:<video> 的 src 不能指向裸 MP4 路径(如 /videos/demo.mp4),否则 Nginx/Apache 会直出,绕过所有逻辑。
为什么禁用 MediaSource 或隐藏控件没用
有人试图在 JS 中禁用 MediaSource(如改写 window.MediaSource = undefined)或用 CSS 隐藏右键菜单、控制栏,这些操作完全无效:
- 禁用
MediaSource只会影响 HLS/DASH 类动态加载,对直接src播放的 MP4 无影响 - 隐藏控件不影响 Network 面板里一眼看到真实请求地址,更拦不住抓包工具(如 Charles)或录屏软件
- 用户禁用 JS 后,
<video controls>依然能正常播,所有“前端防护”瞬间失效
这类做法唯一效果是增加自己调试成本,还可能触发浏览器媒体错误(如 MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED)。
真正有效的边界在服务端和 CDN
防跨站播放不是前端任务,而是服务端策略问题。落地时必须做到:
- 视频文件不放在静态目录,全部走应用层接口(如
GET /api/video/:id) - 接口响应头设置
Content-Disposition: attachment; filename="forbidden.mp4"(可选,增加下载障碍) - CDN 配置防盗链:开启 Referer 白名单 + 签名 URL + UA 限制(如屏蔽
curl、ffmpeg等工具 UA) - 对高频 IP 做限速(如单 IP 每分钟最多请求 5 次视频分片)
复杂点在于:移动端 WebView、PWA、iframe 嵌套等场景下 Referer 不稳定,必须用 token + session 绑定做兜底。别指望一个配置通吃所有环境。



















