如何防止水印被恶意删除或者隐藏?

继上篇 Vue3 实现网页背景水印功能 我们了解了常见的网页水印功能是如何实现的,懂原理的都知道水印是通过在网页中添加代码绘制 DOM 元素覆盖在原有的网页上而来的,一旦你打开浏览器中的元素审查,可以通过删除元素或者在元素的样式上操作属性值,就可以用来临时屏蔽水印。

为了防止作弊,我们可以利用接口 MutationObserver 对 DOM 元素进行监听。如果你对监听的元素进行样式属性的设置,或者对监听元素的子元素进行删除,都能通过 MutationObserver 的回调函数进行捕获,然后再针对你的修改操作进行复原。这样可以有效防止临时操作网页元素来隐藏水印。

MutationObserver 接口提供了监视对 DOM 树所做更改的能力。它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。

// 选择需要观察变动的节点
const targetNode = document.getElementById('some-id');// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };// 当观察到变动时执行的回调函数
const callback = function(mutationsList, observer) {// Use traditional 'for loops' for IE 11for(let mutation of mutationsList) {if (mutation.type === 'childList') {console.log('A child node has been added or removed.');}else if (mutation.type === 'attributes') {console.log('The ' + mutation.attributeName + ' attribute was modified.');}}
};// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);// 以上述配置开始观察目标节点
observer.observe(targetNode, config);// 之后,可停止观察
observer.disconnect();

了解如何使用之后,我们对上篇封装的增加水印功能的 hooks 进行优化,添加一个防删除的方法 antiDeletion,里面对水印元素和它的父级也就是 body进行了监听。

对父级元素进行监听,是为了捕获对它的删除操作,mutation 的类型为 childList,当删除水印元素的时候,我们通过回调参数 removedNodes 拿到删除元素的内容后再往它的父节点动态插入水印元素,相当于未删除成功。

a8c2c88b0439ca746ed517dffd2aa22e.png

然后还需要防止用户对水印元素进行样式属性的设置,比如 display: none;隐藏元素内容。这个时候我们添加对水印 DIV 层的监听,通过对 mutation 类型为attributes 的判断,然后强制给可能导致水印显示变化的样式进行复原操作。

const observers = [];
function antiDeletion() {const targetNode = unref(watermarkEl);const parentNode = unref(appendEl);const config = {childList: true,attributes: true,attributeOldValue: true,characterData: true,characterDataOldValue: true};observers[0] = new MutationObserver((mutationList, _observer) => {for (const mutation of mutationList) {const type = mutation.type;switch (type) {case "childList":console.log("childList", mutation);if (mutation.removedNodes.length > 0) {parentNode.appendChild(mutation.removedNodes[0]);}break;default:break;}}});observers[0].observe(parentNode, { childList: true });observers[1] = new MutationObserver((mutationList, _observer) => {for (const mutation of mutationList) {const type = mutation.type;switch (type) {case "attributes":console.log("attributes", mutation);if (mutation.attributeName === "style") {targetNode.style.display = "block";targetNode.style.zIndex = "100000";targetNode.style.top = "0px";targetNode.style.left = "0px";targetNode.style.position = "absolute";}if (mutation.attributeName === "class") {targetNode.style.setProperty("visibility","visible","important");}break;default:break;}}});observers[1].observe(targetNode, config);}

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver

- END -

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jmc线程转储_如何分析线程转储– IBM VM

jmc线程转储本文是我们的线程转储分析系列的第4部分,它将为您提供什么是IBM VM的JVM线程转储以及您将找到的不同线程和数据点的概述。 您将看到和学习​​到,IBM VM Thread Dump格式是不同的,但是提供了更多现成的故障排除数据。 在这一点上&…

java lock

多线程访问同一个变量,不进行同步,会造成结果不一致。这里解决方案有很多,使用原子变量。加锁同步,使用synchronized同步。下面是一个lock demo,后面会分析lock实现原理。lock使用的是公平锁还是非公平锁等 import jav…

Java 8:使用交替接口公开的类型安全地图生成器

动态展示您的课程 当我是Java新手时,我记得当时想过应该有一种方法可以删除或隐藏我不想公开的类中的方法。 就像用private方法或类似方法覆盖public方法一样(哪种情况是不可能的,也不应该是不可能的)。 显然,今天&…

nodejs面试题

1、为什么用Nodejs,它有哪些缺点? 事件驱动,通过闭包很容易实现客户端的生命活期。不用担心多线程,锁,并行计算的问题V8引擎速度非常快对于游戏来说,写一遍游戏逻辑代码,前端后端通用当然Nodejs也有一些缺点…

sts-bundle的使用_使用WS-Trust / STS采样器扩展JMeter

sts-bundle的使用JMeter没有对WS-Security或WS-Trust的任何内置支持,这使我为JMeter开发了此STS采样器–可以在负载测试STS时使任何人的生活变得更好。 首先,您需要拥有Apache JMeter发行版。 我正在使用v2.7。 然后,您可以从此处下载sts.sam…

001_jdk配置

配置JAVA_HOME,CLASSPATH,PATH 其中JAVA_HOME必须的 JAVA_HOMEE:\java\jdk1.8.0_77 CLASSPATH(告诉java程序运行时,你的类或者类库在哪里) .; E:\java\jdk1.8.0_77\lib\dt.jar;E:\java\jdk1.8.0_77\lib\tools.jar;E:\java\jdk1.8.0_77\jre\lib\rt.jar 改成变量 .;%J…

Spring MVC 4快速入门Maven原型得到了改进–更多Java 8功能

对于所有有兴趣在没有Spring Boot的情况下快速引导Spring 4应用程序的开发人员,请检查刚刚更新的我的Spring MVC 4 Quickstart Maven原型。 原型已经将Java 8用作目标平台已有一段时间了,但是不支持特定的Java 8功能。 最近的更改带来了Thymeleaf&#x…

python -- join()

python -- join()pythonjoinos月似当时,人似当时否?总 在 python 中,一共有两个 join 方法,一个是 str.join(),另一个是 os.path.join() ,这里只了解前一种 str.join(iterable) 官方文档 Return a string which is the…

easymock教程_EasyMock教程–入门

easymock教程在本文中,我将向您展示EasyMock是什么,以及如何使用它来测试Java应用程序。 为此,我将创建一个简单的Portfolio应用程序,并使用JUnit&EasyMock库对其进行测试。 在开始之前,让我们首先了解使用…

python 函数、面向对象

一、函数 1、定义个函数,可以对输入的数据进行排序, 通过参数来决定是正向排序还是反向排序。 number input(请输入一串数字:) number_list list(number) def sort_number(*args, s0): if s 0: number_map map(int,args)result sorted…

Spark数据倾斜解决方案(转)

本文转发自技术世界,原文链接 http://www.jasongj.com/spark/skew/ Spark性能优化之道——解决Spark数据倾斜(Data Skew)的N种姿势 发表于 2017-02-28 | 更新于 2017-10-17 | 本文结合实例详细阐明了Spark数据倾斜的几种场景以及对应的解…

JavaParser入门:以编程方式分析Java代码

我最喜欢的事情之一是解析代码并对其执行自动操作。 因此,我开始为JavaParser做出贡献,并创建了两个相关项目: java-symbol-solver和Effectivejava 。 作为JavaParser的贡献者,我反复阅读了一些非常类似的问题,这些问…

python Django基本介绍

创建Django项目并运行 实验环境: Ubuntu 16.04下安装好Anaconda3 Windows下安装好PyCharm 实验步骤 一、创建django工程 在Ubuntu 16.04下执行下面的命令。 (1)创建一个python3的虚拟环境(如果已经创建,忽略此步&…

Android 热补丁动态修复框架小结

Android 热补丁动态修复框架小结转载于:https://www.cnblogs.com/zhujiabin/p/7923233.html

C语言中关于结构体的理解

在c语言中我们如果需要去表示一个学生的特征,例如名字年龄成绩,这些信息我们就需要用到结构体来描述了。 struct stu{char name[20]; //姓名int age; //年龄float score; //成绩 }; struct(结构体):是由一系列具有相同类型…

GoldenGate Logdump基本使用

Logdump是GoldenGate复制软件中附带的一个工具软件,在OGG的目录下可以找到。这个工具主要用于分析OGG生成的队列文件,查找记录、统计队列文件中的数据等。 在OGG安装目录下执行logdump.exe or ./logdump即可进入命令行。 开始查找记录之前,先…

js 里面的键盘事件对应的键码

js 里面的键盘事件经常用到,所以收集了键盘事件对应的键码来分享下: keyCode 8 BackSpace BackSpace keyCode 9 Tab Tab keyCode 12 Clear keyCode 13 Enter keyCode 16 Shift_L keyCode 17 Control_L keyCode 18 Alt_L keyCode 19 Pause keyCo…

.bam.bai的意义_业务活动监视器(BAM)2.0带来的革命

.bam.bai的意义生产兼具精益和企业价值的中间件是一项艰巨的工作。 它要么不存在,要么需要创新的思维(很多),并且需要在实现中反复进行。 业务风险很大,但是如果您做对了,它就会使您领先于其他任何公司。 这…

数据结构和算法之排序五:选择排序

我们上一篇谈到了冒泡排序,其实我也说了,这两个排序方式何其相似,如果掌握了冒泡排序再来进行选择排序的理解我觉得完全没有太大的问题。那么什么叫做选择排序呢?我们可以理解为矮子里面挑高个,比如说呀有一个富翁来到…

Visual Studio Code使用问题

1、打开vscode黑屏 右击vscode快捷方式–>属性–>兼容性—>兼容模式打钩 重启vscode就可以了。 2、vscode终端没有显示路径,不能输入 显示如下图 则关闭VS Code ,右键单击VS Code 图标,选择属性->兼容性,取消勾选 已兼容模式运…