前端防止用户复制的十种方法总结

 更新时间:2025年12月11日 08:33:38   作者:刘大华  
在我们写前端的时候,有时候会遇到这种禁止用户复杂网页内容的需求,这里来分享几种常见的方法,但是这些方法也不能完全阻止内容被复制,需要的朋友可以参考下

引言

在我们写前端的时候,有时候会遇到这种禁止用户复杂网页内容的需求,这里来分享几种常见的方法,但是这些方法也不能完全阻止内容被复制。

因为用户还是可以通过开发者工具,截图提取文字等等这些方式来进行复制。不过我们也可以在一定程度上提升复制的门槛,防止普通用户随意复制。

以下是几种常用方案:

1.禁用文本选择

使用 CSS 禁止用户选中文本:

body {
  -webkit-user-select: none; /* Safari */
  -moz-user-select: none;    /* Firefox */
  -ms-user-select: none;     /* IE/Edge */
  user-select: none;         /* 标准语法 */
}

也可以针对特定元素设置:

<div style="user-select: none;">这段文字无法被选中</div>

用户仍可查看源代码或使用其他手段复制。

2.监听并阻止复制、剪切、粘贴事件

通过 JavaScript 拦截相关键盘和剪贴板事件:

document.addEventListener('copy', (e) => {
  e.preventDefault();
  alert('复制已被禁止');
});

document.addEventListener('cut', (e) => {
  e.preventDefault();
  alert('剪切已被禁止');
});

document.addEventListener('paste', (e) => {
  e.preventDefault();
  alert('粘贴已被禁止');
});

用户还是可以按下F12禁用 JavaScript 或绕过事件监听。

3.将内容嵌入图片或 Canvas

将关键内容渲染为图片或使用 <canvas> 绘制,使文本不可直接选中:

<img src="text-as-image.png" alt="不可复制的文字">

或使用 canvas 动态绘制:

<canvas id="myCanvas"></canvas>
<script>
  const ctx = document.getElementById('myCanvas').getContext('2d');
  ctx.font = '20px Arial';
  ctx.fillText('这段文字无法复制', 10, 50);
</script>

不利于 SEO、无障碍访问(屏幕阅读器无法读取),且加载慢。

4.用户按F12就出发debug功能

当用户按下F12时,触发debug调试,让用户无法选中页面内容。

<script>
(function antiDebug() {
  let devOpen = false;
  const threshold = 100;

  function check() {
    const start = performance.now();
    debugger;
    const end = performance.now();

    if (end - start > threshold) {
      if (!devOpen) {
        devOpen = true;
        document.body.innerHTML = '<h2>检测到开发者工具,请关闭后重试。</h2>';
        // 可选:上报用户行为
        // fetch('/log-devtools', { method: 'POST' });
      }
    } else {
      devOpen = false;
    }

    setTimeout(check, 1000);
  }

  check();
})();
</script>

5. 动态文本拆分与重组

将文本内容拆分成多个DOM节点,增加复制难度:

<div id="protected-text">
  <!-- 文本将被JavaScript拆分并插入 -->
</div>

<script>
  const text = "这是一段需要保护的机密内容,不能被轻易复制";
  const container = document.getElementById('protected-text');
  
  // 将每个字符用span包裹
  text.split('').forEach(char => {
    const span = document.createElement('span');
    span.textContent = char;
    span.style.display = 'inline-block'; // 增加选择难度
    container.appendChild(span);
  });
</script>

进阶版:随机插入不可见字符或零宽字符:

function obfuscateText(text) {
  const zeroWidthSpace = '\u200B'; // 零宽空格
  return text.split('').map(char => 
    char + zeroWidthSpace.repeat(Math.floor(Math.random() * 3))
  ).join('');
}

const originalText = "保护内容";
document.getElementById('text').textContent = obfuscateText(originalText);

6. 使用CSS伪元素显示内容

通过CSS的::before::after伪元素显示文本:

<style>
.protected-content::before {
  content: "这段文字通过CSS生成,无法直接选中和复制";
}
</style>

<div class="protected-content"></div>

7. 字体反爬虫技术

使用自定义字体文件,将字符映射关系打乱:

@font-face {
  font-family: 'CustomFont';
  src: url('custom-font.woff2') format('woff2');
}

.protected-text {
  font-family: 'CustomFont';
}

在字体文件中,将实际字符与显示字符的映射关系打乱,比如:

  • 字符a在字体中实际显示为b
  • 字符b显示为c,以此类推

后端配合:服务器动态生成字体文件,定期更换映射关系。

8. Canvas + WebGL 渲染文本

使用更复杂的图形渲染技术:

<canvas id="textCanvas" width="800" height="100"></canvas>
<script>
  const canvas = document.getElementById('textCanvas');
  const ctx = canvas.getContext('2d');
  
  // 设置文字样式
  ctx.font = '24px Arial';
  ctx.fillStyle = '#333';
  
  // 绘制干扰元素
  ctx.fillText('保护内容', 50, 50);
  
  // 添加噪声干扰
  for(let i = 0; i < 100; i++) {
    ctx.fillRect(
      Math.random() * 800, 
      Math.random() * 100, 
      1, 1
    );
  }
</script>

9. SVG 文本渲染

使用SVG渲染文本,增加选择难度:

<svg width="400" height="100">
  <text x="10" y="30" font-family="Arial" font-size="20" 
        fill="black" style="user-select: none;">
    这段SVG文本难以复制
  </text>
  <!-- 添加干扰路径 -->
  <path d="M10,40 L390,40" stroke="#eee" stroke-width="1"/>
</svg>

10. 实时DOM监控与修复

监控DOM变化,防止用户通过开发者工具修改内容:

const contentElement = document.getElementById('protected-content');
const originalContent = contentElement.innerHTML;

// 定时检查内容完整性
setInterval(() => {
  if (contentElement.innerHTML !== originalContent) {
    contentElement.innerHTML = originalContent;
    console.log('检测到内容篡改,已恢复');
  }
}, 500);

// 使用MutationObserver更精确的监控
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation.type === 'childList' || mutation.type === 'characterData') {
      contentElement.innerHTML = originalContent;
    }
  });
});

observer.observe(contentElement, {
  childList: true,
  characterData: true,
  subtree: true
});

综合防御策略建议

对于高安全要求的场景,建议采用分层防御

class ContentProtector {
  constructor() {
    this.init();
  }
  
  init() {
    this.disableSelection();
    this.bindEvents();
    this.startMonitoring();
    this.obfuscateContent();
  }
  
  disableSelection() {
    document.head.insertAdjacentHTML('beforeend', `
      <style>
        body { -webkit-user-select: none; user-select: none; }
        .protected { cursor: default; }
      </style>
    `);
  }
  
  bindEvents() {
    // 绑定所有阻止事件
    ['copy', 'cut', 'paste', 'contextmenu', 'keydown'].forEach(event => {
      document.addEventListener(event, this.preventDefault);
    });
  }
  
  preventDefault(e) {
    e.preventDefault();
    return false;
  }
  
  startMonitoring() {
    // 启动各种监控
    this.monitorDevTools();
    this.monitorDOMChanges();
  }
  
  obfuscateContent() {
    // 内容混淆处理
    // ...
  }
  
  monitorDevTools() {
    // 开发者工具检测
    // ...
  }
  
  monitorDOMChanges() {
    // DOM变化监控
    // ...
  }
}

// 初始化保护
new ContentProtector();

总结

这些方法只能防普通用户,防不住真正想复制的人。

因为别人还是可以通过看源码、截图、关掉 JS 等方式绕过限制。

所以建议:

  • 别过度防护,以免影响正常用户和 SEO;
  • 重要内容靠后端控制(比如登录才能看全文);
  • 组合使用几种方法,提高门槛就好,别追求绝对安全。

毕竟前端展示的内容,就默认是能被看到的,也就能被复制的。

以上就是前端防止用户复制的十种方法总结的详细内容,更多关于前端防止用户复制的资料请关注脚本之家其它相关文章!

相关文章

  • JavaScript中的数组操作介绍

    JavaScript中的数组操作介绍

    这篇文章主要介绍了JavaScript中的数组操作介绍,本文讲解了join()、reverse()、sort()、concat()、slice()、splice()等几个函数的操作实例,需要的朋友可以参考下
    2014-12-12
  • js实现随机div颜色位置 类似满天星效果

    js实现随机div颜色位置 类似满天星效果

    这篇文章主要为大家详细介绍了js实现随机div颜色位置,类似满天星效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • js数组forEach实例用法详解

    js数组forEach实例用法详解

    在本篇文章里小编给大家整理了一篇关于js数组forEach实例用法详解内容,有需要的朋友们可以跟着学习参考下。
    2021-10-10
  • 纯js实现隔行变色效果

    纯js实现隔行变色效果

    这篇文章主要为大家详细介绍了纯js实现隔行变色效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 使用JavaScript实现node.js中的path.join方法

    使用JavaScript实现node.js中的path.join方法

    Node.JS中的 path.join 非常方便,能直接按相对或绝对合并路径,有时侯前端也需要这种方法,如何实现呢?感兴趣的朋友跟随脚本之家小编一起看看吧
    2018-08-08
  • 小程序最新获取用户昵称和头像的方法总结

    小程序最新获取用户昵称和头像的方法总结

    这篇文章主要介绍了小程序最新获取用户昵称和头像的方法总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 瀑布流的实现方式(原生js+jquery+css3)

    瀑布流的实现方式(原生js+jquery+css3)

    这篇文章主要为大家详细介绍了原生js+jquery+css3实现瀑布流的相关代码,三种实现瀑布流的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • 微信小程序支付前端源码

    微信小程序支付前端源码

    这篇文章主要为大家详细介绍了微信小程序支付前端源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • 带你彻底搞懂JavaScript的事件流

    带你彻底搞懂JavaScript的事件流

    这篇文章主要为大家详细介绍了JavaScript的事件流,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Javascript的原型和原型链你了解吗

    Javascript的原型和原型链你了解吗

    这篇文章主要为大家详细介绍了Javascript的原型和原型链,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03

最新评论