移动端水印防截图真的有效吗?

欧阳佳佳 阅读 23

我在做公司内部的保密页面,加了 canvas 水印,但发现用户一截图还是能完整保存内容,根本拦不住啊。

我试过用 pointer-events: none 防止选中,也监听了 visibilitychange 事件隐藏敏感信息,但截图工具绕过这些完全没压力。有没有真正有效的前端方案?

目前水印是这样加的:

const watermark = document.createElement('canvas');
watermark.width = 200;
watermark.height = 100;
const ctx = watermark.getContext('2d');
ctx.font = '16px Arial';
ctx.fillStyle = 'rgba(0,0,0,0.1)';
ctx.fillText('机密', 10, 30);
document.body.style.background = <code>url(${watermark.toDataURL()})</code>;
我来解答 赞 0 收藏
二维码
手机扫码查看
1 条解答
UE丶子硕
直接说结论:前端没法真正防住截图,这是浏览器安全模型的限制。只要内容渲染到屏幕上,系统级截图工具就能捕获,你的水印 canvas 再怎么折腾都没用。

但可以恶心一下截图的人,提高一点门槛:

CSS 层面能做的事

/* 禁止选中和 iOS 长按菜单 */
body {
-webkit-user-select: none;
user-select: none;
-webkit-touch-callout: none;
}

/* 水印混合模式,让它更难被去掉 */
.watermark {
mix-blend-mode: multiply;
pointer-events: none;
}


JS 层面能恶心人的

// 禁用右键菜单
document.addEventListener('contextmenu', e => e.preventDefault());

// 禁用复制
document.addEventListener('copy', e => e.preventDefault());

// 页面可见性变化时清空剪贴板(恶心但有用)
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
navigator.clipboard.writeText('');
}
});


你的水印可以这样改进

// 动态生成更密集的水印,覆盖整个页面
function createWatermark(text) {
const canvas = document.createElement('canvas');
canvas.width = 300;
canvas.height = 150;
const ctx = canvas.getContext('2d');

ctx.font = '14px Arial';
ctx.fillStyle = 'rgba(0,0,0,0.08)';
ctx.rotate(-0.3);
ctx.fillText(text, 20, 50);

return canvas.toDataURL();
}

// 每秒微调位置,打破某些自动截图工具
setInterval(() => {
document.body.style.backgroundPosition = Math.random() * 10 + 'px';
}, 1000);


说点实际的

这些手段只能防小白,真要保密的东西别放前端。服务端做权限控制,敏感数据不返回给无权用户,或者用 SSE/WebSocket 实时推送,显示完就从 DOM 删掉。

说到底,截图是系统权限,前端管不了。你能做的就是提高破解成本,以及别把真正敏感的东西裸放在页面上。
点赞
2026-03-10 20:00