前端面试宝典---前端水印

明水印

1. 背景图

通过css的background-image加载背景图

2. canvas+background水印

前端水印实现思路与示例代码

一、核心实现思路
  1. Canvas动态生成水印

    通过Canvas绘制文本或图案,将生成的图像转为Base64格式,作为背景图重复平铺到目标元素上。例如:

    javascript 复制代码
    function createWatermark(text) {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      canvas.width = 200;
      canvas.height = 150;
      ctx.font = '12px Arial';
      ctx.fillStyle = 'rgba(200,200,200,0.2)';
      ctx.rotate(-30 * Math.PI / 180); // 倾斜角度
      ctx.fillText(text, 10, 100);
      return canvas.toDataURL('image/png');
    }
  2. 防篡改机制

    • 使用MutationObserver监听DOM变化,若水印元素被删除则重新注入
    • 禁止控制台操作:禁用右键菜单、屏蔽开发者工具快捷键
    javascript 复制代码
    document.addEventListener('contextmenu', e => e.preventDefault());
  3. 容器绑定

    将水印作为独立图层覆盖在目标内容上方,通过CSS确保全屏状态仍可见:

    css 复制代码
    .watermark-container {
      position: relative;
    }
    .watermark-layer {
      position: absolute;
      pointer-events: none;
      z-index: 9999;
      background: url('data:image/png;base64,...');
    }
二、完整示例代码
html 复制代码
<!DOCTYPE html>
<html>

<body>
  <style>
    .watermark-container {
      position: relative;
    }

    .watermark-layer {
      position: absolute;
      pointer-events: none;
      z-index: 9999;
      background: url('data:image/png;base64,...');
    }
  </style>
  <div id="content">需要保护的内容</div>

  <script>
    function createWatermark (text) {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      canvas.width = 200
      canvas.height = 150
      ctx.font = '12px Arial'
      ctx.fillStyle = 'rgba(200,200,200,0.2)'
      ctx.rotate(-30 * Math.PI / 180) // 倾斜角度
      ctx.fillText(text, 10, 100)
      return canvas.toDataURL('image/png')
    }

    function initWatermark (text = '机密文件') {
      const watermark = document.createElement('div')
      watermark.style.backgroundImage = `url(${createWatermark(text)})`
      watermark.style.position = 'fixed'
      watermark.style.top = 0
      watermark.style.bottom = 0
      watermark.style.right = 0
      watermark.style.left = 0

      watermark.style.pointerEvents = 'none'

      // 防删除监听
      const observer = new MutationObserver(mutations => {
        if (!document.contains(watermark)) {
          document.body.appendChild(watermark)
        }
      })
      observer.observe(document.body, { childList: true })

      document.body.appendChild(watermark)
    }

    initWatermark('严禁复制');
  </script>
</body>

</html>
三、注意事项
  1. 动态水印

    可添加时间戳、用户ID等可变信息增强追踪能力:

    javascript 复制代码
    const dynamicText = `${username} ${new Date().toLocaleString()}`;
  2. 样式优化

    • 使用background-repeat: repeat平铺
    • 调整rgba透明度值平衡可见性与内容遮挡
  3. 跨框架实现

    Vue/React可通过高阶组件封装水印逻辑,例如:

    js 复制代码
    const withWatermark = (Component) => (props) => (
      <div className="watermark-wrapper">
        <Component {...props} />
      </div>
    )

纯canvas水印

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Canvas水印示例</title>
  <style>
    .watermark {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1000;
      pointer-events: none;
      opacity: 0.2;
    }
  </style>
</head>
<body>
  <canvas id="watermarkCanvas" class="watermark"></canvas>
  <div>
    <h1>内容区域</h1>
    <p>这是需要加水印的内容</p>
  </div>
  <script>
    window.onload = function() {
      var canvas = document.getElementById('watermarkCanvas');
      var ctx = canvas.getContext('2d');
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;

      var text = '水印文本';
      var width = canvas.width;
      var height = canvas.height;
      ctx.font = '30px Arial';
      ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';

      // 旋转并重复绘制水印文本
      for (var x = 0; x < width; x += 200) {
        for (var y = 0; y < height; y += 200) {
          ctx.save();
          ctx.translate(x, y);
          ctx.rotate(- Math.PI / 4);
          ctx.fillText(text, 0, 0);
          ctx.restore();
        }
      }
    };
  </script>
</body>
</html>

svg水印

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SVG水印示例</title>
  <style>
    .watermark {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1000;
      pointer-events: none;
      opacity: 0.2;
    }
  </style>
</head>
<body>
  <div class="watermark">
    <svg width="100%" height="100%">
      <text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="30" fill="rgba(0,0,0,0.1)" transform="rotate(-45, 50, 50)">水印文本</text>
    </svg>
  </div>
  <div>
    <h1>内容区域</h1>
    <p>这是需要加水印的内容</p>
  </div>
</body>
</html>
相关推荐
#麻辣小龙虾#13 分钟前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar18 分钟前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github
weixin_4713830331 分钟前
Taro-02-页面路由
前端·taro
星栈独行38 分钟前
Makepad 应用如何读文件、调接口、保存数据
前端·程序人生·ui·rust·github
IT_陈寒1 小时前
Vite热更新失效?可能你在用Windows
前端·人工智能·后端
tedcloud1232 小时前
taste-skill部署教程:打造个性化AI推荐工作流
服务器·前端·人工智能·系统架构·edge
xinhuanjieyi2 小时前
html修复游戏种太阳错误
前端·游戏·html
林希_Rachel_傻希希3 小时前
学React治好了我的焦虑症,1小时速通React 前20分钟。
前端·javascript·面试
Cache技术分享3 小时前
435. Java 日期时间 API - Clock 灵活获取当前时间
前端·后端
独泪了无痕4 小时前
Vue3中防御XSS攻击的“特效药”-DOMPurify
前端·vue.js·安全