纯前端无法真正防截屏,仅能通过动态canvas水印增加截图干扰:倾斜15°、透明度0.08、随机偏移±20px、每300ms重绘,并适配devicepixelratio。

HTML防截屏水印本质是“视觉干扰”,不是技术封锁
直接说结论:纯前端 HTML/CSS/JS 无法真正阻止截图,所谓“防截屏”只是通过动态覆盖、高频率扰动、DOM 干扰等方式提高截图成本和可用性——截图依然能成功,但截出来的图带明显水印、文字错位或闪烁,难以用于盗用。别信“100%防截屏”的宣传,那是误导。
用 canvas 叠加实时动态水印最可控
比 CSS 伪元素或固定背景图更难绕过:canvas 内容可编程生成(含用户 ID、时间戳)、支持透明度渐变、坐标随机偏移,且能响应 resize 和 scroll 重绘。关键点:
- 水印文字必须倾斜(
rotate(15))、低透明(globalAlpha = 0.08)、大间距(避免连成可读块) - 每个水印块位置用
Math.random()偏移 ±20px,防止被脚本批量清除 DOM 节点 - 绘制频率控制在每 300ms 重绘一次,太密卡顿,太疏易被静帧捕获
- 务必监听
window.devicePixelRatio,否则高清屏下水印模糊或过细
const drawWatermark = () => {
const canvas = document.getElementById('watermark-canvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.08;
ctx.font = '16px Microsoft YaHei';
ctx.fillStyle = '#000';
ctx.rotate(-Math.PI / 12);
for (let i = 0; i <h3>
<code>pointer-events: none</code> 和 <code>z-index</code> 配合不当会导致水印失效</h3><p>常见错误:把水印层设为 <code>position: fixed</code> 但没加 <code>pointer-events: none</code>,结果用户点不到底下的按钮;或者 <code>z-index</code> 被其他组件(如 antd 的 <code>.ant-modal</code>)覆盖,水印直接看不见。实操要点:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img
src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="overflowclass">Wechat HTML Publisher</a>
<p class="overflowclass">直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p>
</div>
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 水印容器必须设
pointer-events: none,内部所有子元素也需显式继承(* { pointer-events: none; }) -
z-index值建议 ≥ 9999,且检查是否被transform或iframe创建新 stacking context 覆盖 - 若页面有
iframe,水印无法跨域覆盖其内容——这是浏览器安全限制,无解 - 移动端要额外加
-webkit-user-select: none,防止长按触发文字选择框遮挡水印
服务端注入水印文本比前端拼接更安全
前端硬编码水印内容(如 document.getElementById('user-id').innerText)容易被 DevTools 修改或绕过。推荐做法:
- 后端渲染时将加密后的用户标识写入
data-watermark属性: - 前端 JS 解密该值(简单 Base64 或 AES-CBC,密钥由后端动态下发),再喂给 canvas 绘制逻辑
- 避免在 JS 中明文出现敏感字段(如邮箱、手机号),哪怕只是水印用途
- 注意 SSR 场景下首次渲染时 canvas 可能未挂载,需用
requestAnimationFrame延迟绘制
真正难防的是录屏+OCR 提取文字,以及用户用另一台设备拍照。动态水印只抬高第一道门槛,别把它当保险柜用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










