谈谈前端如何防止数据泄漏

shigen日更文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。

最近突然发现了一个好玩的事情,部分网站进去的时候几乎都是死的,那种死是区别于我们常见的网站的死:

  • 不能选中文字
  • 不能复制粘贴文字
  • 不能鼠标右键显示选项
  • 不能打开控制台
  • ......

各种奇葩的操作应接不暇,像极了我最初接触的某库。shigen的好奇心直接拉满,好家伙,这是咋做的呀。一顿操作之后,发现这种是为了防止网站的数据泄露(高大上)。在我看来,不是为了装X就是为了割韭菜。

咱废话也不多说,就手动来一个,部分代码参考文章:如何防止网站信息泄露(复制/水印/控制台)

shigen实现的效果是这样的:

用魔法生成了一个页面,展示的是李白的《将进酒》。我需要的功能有尽可能的全面,禁止复制、选择、调试......

找了很多的方式,最后能自豪的展示出来的功能有:

  • 禁止选择
  • 禁止鼠标右键
  • 禁止复制粘贴
  • 禁止调试资源(刷新页面的方式)
  • 常见的页面水印

那其实也没有特别的技术含量,我就在这里展示了,希望能作为工具类供大家使用。

页面部分

html5+css,没啥好讲的。

html 复制代码
 <!DOCTYPE html>
 <html lang="zh-CN">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <style>
         body {
             font-family: "Microsoft YaHei", sans-serif;
             line-height: 1.6;
             padding: 20px;
             text-align: center;
             background-color: #f8f8f8;
         }
 ​
         .poem-container {
             max-width: 600px;
             margin: 0 auto;
             background-color: #fff;
             padding: 20px;
             border-radius: 8px;
             box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
         }
 ​
         h1 {
             font-size: 1.5em;
             margin-bottom: 20px;
         }
 ​
         p {
             text-indent: 2em;
             font-size: 1.2em;
         }
     </style>
     <title>李白《将进酒》</title>
 </head>
 ​
 <body>
     <div class="poem-container">
         <h1>将进酒</h1>
         <p>君不见,黄河之水天上来,奔流到海不复回。</p>
         <p>君不见,高堂明镜悲白发,朝如青丝暮成雪。</p>
         <p>人生得意须尽欢,莫使金樽空对月。</p>
         <p>天生我材必有用,千金散尽还复来。</p>
         <p>烹羊宰牛且为乐,会须一饮三百杯。</p>
         <p>岑夫子,丹丘生,将进酒,杯莫停。</p>
         <p>与君歌一曲,请君为我倾耳听。</p>
         <p>钟鼓馔玉不足贵,但愿长醉不复醒。</p>
         <p>古来圣贤皆寂寞,惟有饮者留其名。</p>
         <p>陈王昔时宴平乐,斗酒十千恣欢谑。</p>
         <p>主人何为言少钱,径须沽取对君酌。</p>
         <p>五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。</p>
     </div>
  </body>

js部分

禁止选中

javascript 复制代码
 // 防止用户选中
 function disableSelect() {
     // 方式:给body设置样式
     document.body.style.userSelect = 'none';
 ​
     // 禁用input的ctrl + a
     document.keyDown = function(event) {
         const { ctrlKey, metaKey, keyCode } = event;
         if ((ctrlKey || metaKey) && keyCode === 65) {
             return false;
         }
     }
 };

禁止复制、粘贴、剪切

javascript 复制代码
 document.addEventListener('copy', function(e) {
     e.preventDefault();
 });
 document.addEventListener('cut', function(e) {
     e.preventDefault();
 });
 document.addEventListener('paste', function(e) {
     e.preventDefault();
 });

禁止鼠标右键

javascript 复制代码
 // 防止右键
 window.oncontextmenu = function() {
     event.preventDefault()
     return false
 }

禁止调试资源

这个我会重点分析。

javascript 复制代码
 let threshold = 160 // 打开控制台的宽或高阈值  
 window.setInterval(function() {
     if (window.outerWidth - window.innerWidth > threshold ||
         window.outerHeight - window.innerHeight > threshold) {
         // 如果打开控制台,则刷新页面  
         window.location.reload()
     }
 }, 1000)

这个代码的意思很好理解,当我们F12的时候,页面的宽度肯定会变小的,我们这个时候和屏幕的宽度比较,大于我们设置的阈值,我们就算用户在调试页面了。这也是我目前找到的比较好的方式了。但是,但是,认真思考一下以下问题需要你考虑吗?

  • 页面频繁加载,流量的损失大吗
  • 页面刷新,后端接口频繁调用,接口压力、接口幂等性

所以,我觉得这种方式不优雅,极度的不优雅,但是有没有别的好的解决办法。

加水印

javascript 复制代码
 // 生成水印
 function generateWatermark(keyword = 'shigen-demo') {
     // 创建Canvas元素  
     const canvas = document.createElement('canvas');
     const context = canvas.getContext('2d');
 ​
     // 设置Canvas尺寸和字体样式  
     canvas.width = 100;
     canvas.height = 100;
     context.font = '10px Arial';
     context.fillStyle = 'rgba(0,0,0,0.1)';
 ​
     // 绘制文字到Canvas上  
     context.fillText(keyword, 10, 50);
 ​
     // 生成水印图像的URL  
     const watermarkUrl = canvas.toDataURL();
 ​
     // 在页面上显示水印图像(或进行其他操作)  
     const divDom = document.createElement('div');
     divDom.style.cssText = `
         position: fixed;
         z-index: 99999;
         top: -10000px;
         bottom: -10000px;
         left: -10000px;
         right: -10000px;
         transform: rotate(-45deg);
         pointer-events: none;
         background-image: url(${watermarkUrl});
     `;
     document.body.appendChild(divDom);
 }

代码不需要理解,部分的参数去调整一下,就可以拿来就用了。

我一想,我最初接触到这种页面水印的时候,是在很老的OA办公系统,到后来用到了某书,它的app页面充满了水印,包括浏览器端的页面。

所以,我也实现了这个。but,but,有一种技术叫做OCR,大白话讲就是文字识别。我把图片截个图,让某信、某书识别以下,速度和效果那叫一个nice,当然也可能把水印也识别出来了。聪敏的开发者会把水印的颜色和文字的颜色设置成一种,这个时候需要准确的文字那可得下一番功夫了。换句话说,不是定制化的OCR,准确的识别出信息,真的够呛。

还有的很多页面实现了js的数据加密、接口数据加密。但是道高一尺,魔高一丈,各种都是在一种相互进步的。就看实际的业务场景和系统的设计了。


以上就是今天分享的全部内容了,觉得不错的话,记得点赞 在看 关注支持一下哈,您的鼓励和支持将是shigen坚持日更的动力。同时,shigen在多个平台都有文章的同步,也可以同步的浏览和订阅:

平台 账号 链接
CSDN shigen01 shigen的CSDN主页
知乎 gen-2019 shigen的知乎主页
掘金 shigen01 shigen的掘金主页
腾讯云开发者社区 shigen shigen的腾讯云开发者社区主页
微信公众平台 shigen 公众号名:shigen

shigen一起,每天不一样!

相关推荐
qq_3901617728 分钟前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test1 小时前
js下载excel示例demo
前端·javascript·excel
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶1 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo1 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
知孤云出岫1 小时前
web 渗透学习指南——初学者防入狱篇
前端·网络安全·渗透·web
贩卖纯净水.1 小时前
Chrome调试工具(查看CSS属性)
前端·chrome
栈老师不回家2 小时前
Vue 计算属性和监听器
前端·javascript·vue.js