前端防复制仅对普通用户有轻微干扰,无法真正限制复制和右键;敏感内容必须依赖服务端处理,如动态水印、分片加载、Canvas渲染或权限校验。

不能真正限制复制和右键,所有前端手段都只对普通用户构成轻微干扰;敏感内容必须靠服务端处理,比如动态水印、分片加载、Canvas 渲染或权限校验。
oncontextmenu="return false" 只拦鼠标右键,不防 Shift+F10 和长按
这是最常用也最容易误解的写法。它只在鼠标右键点击时触发,且必须写在 HTML 属性里才可靠:oncontextmenu="return false"。放在 <body> 上能覆盖大部分子元素,但以下情况完全无效:
- 用户按
Shift+F10或用触摸屏长按(iOS/Android 原生菜单不走该事件) - 页面里有
<iframe>,需单独对其contentDocument绑定,否则 iframe 内右键照常弹出 - 开发者工具打开后执行
document.oncontextmenu = null,立刻恢复右键 - 禁用 JavaScript 后,整个逻辑彻底失效
user-select: none 必须带全前缀,且只禁拖选不防 Ctrl+C
仅写 user-select: none 在旧版 Chrome、Safari、Firefox 中基本无效。必须同时声明:
div.protected {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
但要注意:
立即学习“前端免费学习笔记(深入)”;
- 该样式对
<input>、<textarea>、contenteditable元素自动失效,浏览器会忽略 - 不影响
Ctrl+A全选,尤其当 DOM 结构扁平(如纯<p>堆叠)时,全选后Ctrl+C仍可复制 - 移动端长按唤起的“复制”菜单不受任何影响
- 别直接套在
<body>上——否则所有按钮、链接焦点异常,得额外给交互元素重置user-select: text
监听 copy 事件要精准过滤,否则废掉所有输入框
相比 CSS 和 oncontextmenu,copy 事件是目前最可控的复制拦截点,但极易误伤:
- 必须用
e.preventDefault(),只写return false无效 - 不能全局监听
document.addEventListener('copy', ...),否则<input>和<textarea>的复制粘贴功能全部瘫痪 - 推荐条件判断:
if (!e.target.matches('input, textarea, [contenteditable="true"]')) { e.preventDefault(); } - Safari 对该事件支持极不稳定,部分 iOS 设备复制动作已完成才触发回调;Android Chrome 基本不触发
- 无法拦截通过 DevTools 控制台执行的
navigator.clipboard.writeText()或document.body.innerText
真正需要保护的内容,前端连门都算不上
所谓“防盗”只是心理门槛。用户禁用 JS、用 curl 抓 HTML、打开 view-source:、从 Network 面板拷响应体、甚至截图 OCR,都能绕过所有前端限制。最容易被忽略的点是:
- 所有文字内容只要出现在 DOM 里,就等于公开——哪怕加了水印、用了 Canvas 渲染,只要没服务端鉴权,爬虫照样提取
- 移动端长按、双击选词、键盘方向键扩展选区,这些行为完全不受
user-select或oncontextmenu约束 - 混淆文字(如 Unicode 同形字)、服务端动态渲染、PDF 替代 HTML、关键段落转 Canvas 文本,才是实际可用的防护层级



















