2020-11-21 09:20:27
JS实现前端水印防截屏的4种方案如下,每种方案均包含实现原理、代码示例及适用场景分析:
1. Canvas水印原理:通过Canvas动态生成水印图片并设置为页面背景,实现简单但防御性较弱。代码示例:
function addCanvasWatermark(settings) { const defaultSettings = { text: '水印文字', font: '16px Arial', color: 'rgba(0, 0, 0, 0.2)', rotate: -20, width: 200, height: 150 }; const options = Object.assign({}, defaultSettings, settings); const canvas = document.createElement('canvas'); canvas.width = options.width; canvas.height = options.height; const ctx = canvas.getContext('2d'); ctx.translate(options.width / 2, options.height / 2); ctx.rotate(options.rotate * Math.PI / 180); ctx.font = options.font; ctx.fillStyle = options.color; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(options.text, 0, 0); const base64Url = canvas.toDataURL(); document.body.style.backgroundImage = `url(${base64Url})`;}// 使用示例addCanvasWatermark({ text: 'Protected Content', color: 'rgba(255, 0, 0, 0.3)' });适用场景:
优势:实现简单,兼容性好。局限:易通过开发者工具移除或覆盖。

原理:创建多个绝对定位的DOM元素覆盖页面,通过透明度与旋转增强视觉效果。代码示例:
function addDOMWatermark(settings) { const defaultSettings = { text: '水印文字', font: '16px Arial', color: 'rgba(0, 0, 0, 0.2)', rotate: -20, zIndex: 1000 }; const options = Object.assign({}, defaultSettings, settings); const container = document.createElement('div'); container.style.position = 'fixed'; container.style.top = '0'; container.style.left = '0'; container.style.width = '100%'; container.style.height = '100%'; container.style.zIndex = options.zIndex; container.style.pointerEvents = 'none'; for (let i = 0; i < 10; i++) { for (let j = 0; j < 10; j++) { const watermarkText = document.createElement('div'); watermarkText.innerText = options.text; watermarkText.style.position = 'absolute'; watermarkText.style.top = `${i * 10}%`; watermarkText.style.left = `${j * 10}%`; watermarkText.style.font = options.font; watermarkText.style.color = options.color; watermarkText.style.transform = `rotate(${options.rotate}deg)`; watermarkText.style.textAlign = 'center'; watermarkText.style.width = '100%'; watermarkText.style.userSelect = 'none'; container.appendChild(watermarkText); } } document.body.appendChild(container);}// 使用示例addDOMWatermark({ text: 'Confidential', color: 'rgba(0, 0, 255, 0.3)', zIndex: 9999 });适用场景:
优势:比Canvas水印更难移除,视觉效果灵活。局限:大量DOM节点可能影响性能,仍可通过CSS覆盖。

原理:结合DOM水印,通过监听DOM变化自动恢复被移除的水印。代码示例:
function addPersistentDOMWatermark(settings) { const watermarkContainer = addDOMWatermark(settings); // 复用DOM水印函数 const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.removedNodes) { mutation.removedNodes.forEach(node => { if (node === watermarkContainer) addDOMWatermark(settings); }); } if (mutation.type === 'attributes' && mutation.target === watermarkContainer) { addDOMWatermark(settings); // 样式被修改时恢复 } }); }); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });}// 使用示例addPersistentDOMWatermark({ text: 'Internal Use Only', color: 'rgba(128, 128, 128, 0.4)', zIndex: 9998 });适用场景:
优势:自动恢复被移除的水印,增强防御能力。局限:代码复杂度高,可能被禁用MutationObserver。
4. SVG水印原理:利用SVG的矢量特性生成可伸缩水印,作为背景或嵌入DOM。代码示例:
function addSVGWatermark(settings) { const defaultSettings = { text: '水印文字', font: '16px Arial', color: 'rgba(0, 0, 0, 0.2)', rotate: -20, width: 200, height: 150 }; const options = Object.assign({}, defaultSettings, settings); const svg = `<svg xmlns="适用场景:
优势:矢量图形无损缩放,修改难度较高。局限:仍可能被覆盖或移除。

降低侵入性:使用浅色、小字体水印。
动态调整密度:根据页面内容自动控制水印数量。
结合后端:关键内容采用后端水印或DRM