vue3前端页面添加水印

2023-11-14

在页面中,往往会添加水印来展示一些信息。例如在一些页面中加上自己特有的信息。使得别人在截图转发时也能看到这些信息。又好比一家公司的内部系统,可以在页面添加访问者的水印,使得用户在截图转发敏感信息之后,通过截图中的水印可以追寻到泄露信息之人。

在最开始实现水印的时候,我的想法是在一个层级比较高的div中添加相关信息,然后循环铺满整个页面。这样 就可以实现页面的水印功能。但是又存在一个新的问题,如果我在页面的代码中将水印中我自己的个人信息改成别人的信息,然后截图传播出去,到时候是不是就追寻不到截图的人了呢?

鉴于这样的情况,我想到了两个方法:①是将水印转换为svg,②是使用canvas绘制水印。

最后我选择了vanvas

于是:便有了如下的代码

function createWaterMark() {
    const angle = -30; //旋转角度
    const txt = props.text; //水印文字
    const canvas = document.createElement('canvas'); //创建画布
    canvas.width = 280; //画布宽
    canvas.height = 200; //画布高
    const ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, 280, 200); //清除画布内容
    ctx.fillStyle = '#000'; //填充颜色
    ctx.globalAlpha = 0.2; //透明度
    ctx.font = `16px YaHei`; //字体属性
    ctx.rotate((Math.PI / 180) * angle); //旋转
    ctx.fillText(txt, 10, 100); //填充字体
    if (props.time) {
        //填充时间
        ctx.fillText(watermark_time, 0, 120);
    }
    if (props.date && !props.time) {
        //填充日期
        ctx.fillText(watermark_date, 0, 120);
    }
    return canvas.toDataURL();
}

在这里我是将水印封装成一个组件,希望能用在不同的系统中,因此水印的内容选择了传值的方式。第一行是用户信息,第二行可以选择带时间的日期和不带时间的日期。

就在这样新增水印之后我正在窃窃自喜的时候我又发现了一个新的问题:如果我在页面的Dom中把该Dom的节点删除了呢?这个时候整个水印就消失不见了。没有水印的页面是在是不安全。

于是,就开始百度…

然后看到一个似乎可以实现的方式:监测Dom,如果该Dom节点被删除了,直接重新刷新页面。

于是,整个水印的操作代码就变成了下面这样:

<template>
    <div></div>
</template>

<script setup>
import moment from 'moment';
import { onMounted, getCurrentInstance } from 'vue';
defineOptions({
    name: 'Watermark',
    inheritAttrs: false
});

const props = defineProps({
    text: String,
    time: Boolean,
    date: Boolean
});
let watermark_date = moment(new Date()).format('YYYY-MM-DD');
let watermark_time = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');

const cb = function (mutationList, observer) {
    for (const mutation of mutationList) {
        if (mutation.type === 'childList') {
            const { removedNodes = [] } = mutation;
            // 如果监听到水印容器变化,那么就重载页面
            const node = Array.prototype.find.apply(removedNodes, [
                (node) => node.className === 'watermark'
            ]);
            //如果水印被删除,重新加载页面
            if (node) {
                window.location.reload();
            }
        }
    }
};

function createWaterMark() {
    const angle = -30; //旋转角度
    const txt = props.text; //水印文字
    const canvas = document.createElement('canvas'); //创建画布
    canvas.width = 280; //画布宽
    canvas.height = 200; //画布高
    const ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, 280, 200); //清除画布内容
    ctx.fillStyle = '#000'; //填充颜色
    ctx.globalAlpha = 0.2; //透明度
    ctx.font = `16px YaHei`; //字体属性
    ctx.rotate((Math.PI / 180) * angle); //旋转
    ctx.fillText(txt, 10, 100); //填充字体
    if (props.time) {
        //填充时间
        ctx.fillText(watermark_time, 0, 120);
    }
    if (props.date && !props.time) {
        //填充日期
        ctx.fillText(watermark_date, 0, 120);
    }
    return canvas.toDataURL();
}
const watermarkDiv = document.createElement('div');
watermarkDiv.className = 'watermark';
watermarkDiv.style.backgroundImage = `url(${createWaterMark()})`;

onMounted(() => {
    const app = document.querySelector('#app');
    //监听Dom改变
    const observer = new MutationObserver(cb);
    observer.observe(app, {
        attributes: true,
        childList: true
    });
    app.appendChild(watermarkDiv);
});
</script>

<style>
.watermark {
    position: fixed;
    width: 100%;
    height: 100%;
    padding: 40px 0 0 0;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    pointer-events: none;
    z-index: 9999999;
    display: flex;
    flex-wrap: wrap;
    overflow: hidden;
}
</style>

在写之前,没想到一个小小的水印还有这么多需要注意的地方。


  • 以上内容仅供参考学习!如有错误,麻烦指正!如有雷同,纯属巧合!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3前端页面添加水印 的相关文章

  • 如何在同一页面上使用AJAX处理多个表单

    我有一个表单 当我单击 提交 时 它就被提交了 然后该表单隐藏 操作页面的结果显示在 div 中 classname dig 它工作正常 但是当我添加另一个表单时 它停止正常工作并且所有表单同时提交 我如何更改我的代码 done click
  • 主干视图 DOM 元素已删除

    我一直在阅读有关 Backbone js 僵尸 或内存泄漏 问题的信息 基本上 当您不再需要该元素时 您必须从 DOM 中解除绑定并删除该元素 以确保所有事件也被删除 现在 我有一个包含几个容器的单页应用程序 div div div div
  • 关闭选项卡时要求确认[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 当我在某些浏览器上关闭页面时 我希望出现一个消息框 并询问我是否真的要关闭页面 有两个按钮 如果我单击No那么这个标签就不会被关闭 我怎样
  • 了解设置 JQuery 变量

    了解设置 JQuery 变量 最近 我通过在 StackOverflow 上遇到的另一个问题寻找帮助 了解到如何设置 JQuery 变量 如下所示 您可以通过简单地调用变量来创建输入字段 并且锚变量似乎也定义了样式 var clicked
  • 不和谐机器人 |不和谐.js |类型错误:无法读取未定义的属性“长度”

    我正在制作一个 Discord 机器人 并且正在使用 CodeLyon 的视频作为参考 该错误位于我的 message js 文件中 该文件包含以下内容 require dotenv config create cooldowns map
  • 如何重定向到 instagram://user?username={username}

    我的 html 页面上有这个链接 可以在特定用户上打开 Instagram 应用程序 a href Link to Instagram Profile a 我一直在寻找自动运行 url instagram user username USE
  • 使用模数按字母顺序对列表进行排序

    我在获取元素列表并按字母顺序对它们进行排序方面没有任何问题 但我很难理解如何使用模数来做到这一点 更新 这是按我的方式工作的代码 但是 我更喜欢下面提供的答案的可重用性 因此接受了该答案
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • 使用 jQuery/JS 打开时使
    标签的内容具有动画效果

    我只想要 HTML5 的内容details标记为 滑行 动画打开 而不是仅仅弹出打开 立即出现 这可以用 jQuery Javascript 实现吗 Fiddle http jsfiddle net 9h4Hq HTML
  • 如何抑制窗口鼠标滚轮滚动...?

    我正在开发嵌入页面中的画布应用程序 我有它 因此您可以使用鼠标滚轮放大绘图 但不幸的是 这会滚动页面 因为它是文章的一部分 当我在 dom 元素上滚动鼠标滚轮时 是否可以阻止鼠标滚轮在窗口上滚动 附加鼠标滚轮 不是 Gecko DOMMou
  • 从未用 @flow 标记的导入文件中获取类型定义

    TL DR我怎么告诉flow从未声明的导入模块导入类型定义 flow 加长版 流接缝能够从不使用流语法的文件中派生类型 请参阅示例 示例文件 flow js if Math random lt 0 5 var y hello else va
  • 在javascript中解析json - 长数字被四舍五入

    我需要解析一个包含长数字的 json 在 java servlet 中生成 问题是长数字被四舍五入 当执行这段代码时 var s x 6855337641038665531 var obj JSON parse s alert obj x
  • Angular 2+ 安全性;保护服务器上的延迟加载模块

    我有一个 Angular 2 应用程序 用户可以在其中输入个人数据 该数据在应用程序的另一部分进行分析 该部分仅适用于具有特定权限的人员 问题是我们不想让未经授权的人知道how我们正在分析这些数据 因此 如果他们能够在应用程序中查看模板 那
  • Laravel 中只向登录用户显示按钮

    如果我以 John 身份登录 如何才能只显示 John 的红色按钮而不显示 Susan 的红色按钮 测试系统环境 Win10 Laravel5 4 Mysql5 7 19 table class table table responsive
  • 在 vue.js 中访问数组对象属性

    给定以下数组vue js packageMaps Object packageMap 0 Object Id 16 PackageType flag list ProductCode F BannerBase packageMap 1 Ob
  • JQuery 图像上传不适用于未来的活动

    我希望我的用户可以通过帖子上传图像 因此 每个回复表单都有一个上传表单 用户可以通过单击上传按钮上传图像 然后单击提交来提交帖子 现在我的上传表单可以上传第一个回复的图像 但第二个回复的上传不起作用 我的提交过程 Ajax 在 php 提交
  • 如何仅在最后一个
  • 处给出透明六边形角度?
  • 我必须制作这样的菜单 替代文本 http shup com Shup 330421 1104422739 My Desktop png http shup com Shup 330421 1104422739 My Desktop png
  • 为什么 jquery 没有检测到单选按钮未被选中的情况? [复制]

    这个问题在这里已经有答案了 可能的重复 JQuery radioButton change 在取消选择期间不会触发 https stackoverflow com questions 5176803 jquery radiobutton c
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 导致回发到与弹出窗口不同的页面

    我有一个主页和一个详细信息页面 详细信息页面是从主页调用的 JavaScript 弹出窗口 当单击详细信息页面上的 保存 按钮时 我希望主页 刷新 是否有一种方法可以调用主页的回发 同时还可以从详细信息页面维护保存回发 Edit 使用win

随机推荐

  • 快速解决数据库连接失败

    无法连接到数据库 以Microsoft SQL Server Management Studio为例 以下简称 SSMS 显示下图连接失败界面 处理方法 打开SQL Server配置管理器 会出现如图服务器状态关闭 此时只需重新启动服务状态
  • RFID标签技术变成仓储物流物流关键技术

    伴随着各种各样电子商务的全方位普及化和市场需求的愈来愈猛烈 怎样完成节约成本 提升工作效能变成持续提升的总体目标 根据创建物流仓储物流运行的自动化技术 信息化 智能化系统 RFID技术变成与公司信息化管理体系的无缝拼接的关键公路桥梁 保证R
  • SpringMVC拦截器(资源和权限管理)

    原文地址 http blog csdn net tonytfjing article details 39207551 1 DispatcherServlet SpringMVC具有统一的入口DispatcherServlet 所有的请求都
  • 大数据技术Flink详解

    一 有状态的流式处理 Apache Flink 是一个分布式流处理器 具有直观和富有表现力的API 可实现有状态的流处理应用程序 它以容错的方式有效地大规模运行这些应用程序 Flink 于2014 年4 月加入Apache 软件基金会作为孵
  • 基于BSC测试网收益聚合器Beefy协议的编译、测试、部署

    前言 文章主要介绍了收益聚合器Beefy协议在币安智能链测试网网上的编译测试部署流程 以Pancake上的USDC BUSD最新Curve版流动池的农场质押为例 详细介绍了完整的操作流程 准备工作 Node js环境 https nodej
  • 在Struts2里面嵌入Spring

    第一步 在web xml中加入下面的listener
  • Linux虚拟地址空间

    目录 父子进程地址相同的变量值不同问题 运行结果 Linux下进程虚拟地址空间分布 什么是虚拟地址空间 进程直接访问物理内存 无虚拟空间 再述虚拟地址空间 虚拟地址空间结构体是如何区域划分 解答最初的问题 延伸问题 一个pid变量怎么可能保
  • [Unity3D]使用触发器实现简单的场景跳转

    学习Unity脚本推荐 Unity3D官网索引 首先一点 你要确保有一个想要跳转的目标场景 在本案例中 目标场景是ending 第一步 创建一个碰撞体 放置在需要的触发场景跳转的位置 第二步 删除多余的脚本 并且新建自己的脚本 第三步 查阅
  • 基数排序图解与代码

    适用范围与背景 前几天写了 计数排序 刚好学习基数排序 我认为基数排序是计数排序的一个补充或者说延伸 因为计数排序不适合 数列元素间差值较大的情况 而基数排序就解决了此情况 它适用于大整数排序 算法思想 不像传统排序算法 两个元素间相互比较
  • Odoo 16最新saas版本说明及源码下载( SaaS-16.3)

    Odoo 16最新saas版本说明及源码下载 SaaS 16 3 Odoo 16最新功能体验 Odoo saas 16 3 下载源码包见文末 新的改变 Odoo 16发布正式版以来 最大改变 超过以前版本的变化 全新的界面设计 将会带来全新
  • FireFly 服务端 Unity3D黑暗世界 客户端 问题

    启动服务端成功截图 连接成功截图 测试服务端是否启动成功 在Web输入 http localhost 11009 按回车 查看cmd启动的服务端 是否多出如下显示 服务端启动成功 PC unity3d客户端 连接也成功 但在手机端连接不成功
  • 5G QoS控制原理专题详解(15)-PDR的定义和UL PDR

    UPF数据包转发原理基本已经写完了 后续修改整理一下错别字就没问题了 这两天会陆续发出来 这样 5G核心网方面的内容写到这里基本就算整理完了 其实如果数据包转发原理部分都弄明白了 PDU Session创建流程的后续部分走马观花的看一看就可
  • 网络编程day5作业

    1 根据select TCP服务器流程图编写服务器 上交 include
  • C语言程序设计·数据类型(例题和知识点)

    1 假设有变量赋值语句x 10 常量10的类型为short 2 假设有变量赋值语句x 2 2 常量2 2的类型是double 3 short int 类型变量的存储数据范围是 32768 32767 4 赋值语句x 082是错误的 5 语句
  • linux下smbd服务,Linux下资源共享服务之samba 的讲解!

    一 Samba 简介 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件 由服务器及客户端程序构成 samba是一个工具套件 在Unix上实现SMB Server Message Block 协议 或者称之为NETBIOS
  • Centos7.6安装confluence7.4.6

    文章目录 环境 JDK安装 MySQL安装 下载confluence 安装 页面配置 实例健康检查 页面乱码问题 环境 名称 配置 centos 7 5 1804 jdk 1 8 0 121 mysql 5 7 confluence 7 4
  • 编译Poco-1.6.0

    下载openssl 下载poco openssl 1 0 2l tar gz config fPIC prefix home developer openssl enable shared make j 4 make install 可选扩
  • javaScript基础面试题 ---对象考点

    1 对象是通过new操作符构建出来的 所以对象之间不相等 2 对象注意引用类型 如果是引用类型 就可能会相等 3 现在对象本身查找 gt 构造函数中找 gt 对象原型中找 gt 构造函数原型中找 gt 对象上一层原型 1 对象是通过new操
  • C语言学习记录-C语言内置类型以及strlen获取长度原则

    C语言内置类型 1 整型int short long long long unsigned int unsigned short unsigned long 2 浮点型float float double long double 3 字符型
  • vue3前端页面添加水印

    在页面中 往往会添加水印来展示一些信息 例如在一些页面中加上自己特有的信息 使得别人在截图转发时也能看到这些信息 又好比一家公司的内部系统 可以在页面添加访问者的水印 使得用户在截图转发敏感信息之后 通过截图中的水印可以追寻到泄露信息之人