javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript动态脱敏指令

基于JavaScript实现一个动态脱敏指令

作者:JYeontu

数据脱敏是指在不影响数据分析结果的准确性前提下,对原始数据中的敏感字段进行处理,从而降低数据敏感度和减少个人隐私风险的技术措施,下面我们就来看看如何实现一个动态脱敏指令吧

所谓的数据脱敏,是指在不影响数据分析结果的准确性前提下,对原始数据中的敏感字段进行处理,从而降低数据敏感度和减少个人隐私风险的技术措施。在现在这个大数据时代,个人隐私信息在互联网上传播的几率是很大的,因此作为前端工程师,我们很多时候也需要在视图层面对数据进行脱敏展示处理。

效果展示

体验地址

http://jyeontu.xyz/jvuewheel/#/JDesensitizationView

指令实现

脱敏函数

参数处理

const desensitization = (str, config, fn) => {
    str = str.trim() + "";
    if (fn) {
        return fn(str);
    }
    if (!str) {
        return "";
    }
    …………
}

配置解析与默认值设定

let { before = 0, after = 0 } = config;
const { type, ch = "*" } = config;
const len = str.length;
switch (type) {
    case "phone":
        before = "3";
        after = "4";
        if (len < 11) {
            before = 2;
            after = 2;
        }
        break;
    case "email":
        before = "1";
        if (str.split("@").length > 1) after = str.split("@")[1].length + 1;
        break;
    case "idCard":
        before = "3";
        after = "4";
        break;
    case "name":
        before = "1";
        after = len > 2 ? 1 : 0;
        break;
}

构造正则进行脱敏

计算出需要显示的真实字符数 show,基于此构建正则表达式 reg。通过 replace 方法,按照正则表达式的匹配规则,用指定的 ch 符号替换中间的敏感字符,最终返回脱敏后的字符串。

const show = Math.max(len - before - after, 0);
const reg = [
    new RegExp(`^(.{${before}}).{${show}}(.{${after}})$`),
    `$1${ch.repeat(show)}$2`,
];
return str.replace(reg[0], reg[1]);

指令执行函数

参数提取与初始值获取

从指令绑定的值 binding.value 中提取出 params,进一步解构得到 config 和 fn。同时获取元素 el 的相关属性值,如 innerHTMLgetAttribute 获取的原始值 originVal,并初始化 inputOriginVal,为后续处理用户输入做准备。

const params = binding.value || {};
const { config, fn } = params;
let inputOriginVal = "";
let originVal = el.getAttribute("desensitization-originVal") || "";

文本节点脱敏处理

当 el.innerHTML 存在时,意味着是对页面展示的文本内容进行脱敏。首先确保 originVal 的获取,若为空则从 el.innerText 中获取并设置为原始值,存储在自定义属性 desensitization-originVal 中,然后调用 desensitization 函数对 originVal 进行脱敏处理,并更新 el.innerHTML

if (el.innerHTML) {
    if (!originVal) {
        el.setAttribute("desensitization-originVal", el.innerText);
        originVal = el.innerText;
    }
    el.innerHTML = desensitization(originVal, config, fn);
    return;
}

输入框交互处理

针对输入框元素,先移除之前可能存在的焦点和失焦事件监听器,避免重复绑定。然后分别为 focus 和 blur 事件添加监听器。在 focus 事件中,将输入框的值恢复为原始输入值 inputOriginVal;在 blur 事件中,获取当前输入值 value,更新 inputOriginVal,并调用 desensitization 函数对 value 进行脱敏处理,最后更新输入框的显示值。

if (fouceListerner) {
    el.removeEventListener("focus", fouceListerner);
}
fouceListerner = el.addEventListener("focus", (event) => {
    event.target.value = inputOriginVal;
});
if (blurListerner) {
    el.removeEventListener("blur", blurListerner);
}
blurListerner = el.addEventListener("blur", (event) => {
    const value = event.target.value;
    inputOriginVal = value;
    const newVal = desensitization(value, config, fn);
    event.target.value = newVal;
});

指令生命周期钩子

bind

当指令首次绑定到元素上时执行。在此处调用 doDesensitization 函数,尝试进行脱敏处理,若出现错误则捕获并打印 bindErr 相关的错误信息,确保指令初始化的稳定性。

bind: function (el, binding) {
    try {
        doDesensitization(el, binding);
    } catch (err) {
        console.error("bindErr", err);
    }
}

update

当指令所在组件的数据更新时触发。首先判断元素 el 的 innerText 是否存在,若存在则调用 doDesensitization 函数进行重新脱敏处理,同样对错误进行捕获并打印 updateErr,保证数据更新后的脱敏效果持续有效。

update: function (el, binding) {
    if (!el.innerText) return;
    try {
        doDesensitization(el, binding);
    } catch (err) {
        console.error("updateErr", err);
    }
}

unbind

当指令从元素上移除时执行。主要任务是移除之前绑定的焦点和失焦事件监听器。

unbind: function (el) {
    if (fouceListerner) {
        el.removeEventListener("focus", fouceListerner);
    }
    if (blurListerner) {
        el.removeEventListener("blur", blurListerner);
    }
}

指令使用

电话号码脱敏

内置有电话的脱敏类型,对于11位数的手机号码,脱敏方式是显示前3位和后4位;对于小于11位数的,比如7位数的电话号码,脱敏方式是显示前2位和后2位。

<div class="content">
    <input
        v-JDesensitization:params="params"
        placeholder="输入需要脱敏的字符"
        class="input-content"
    />
    <div v-JDesensitization:params="params" class="div-content">
        15012345678
    </div>
</div>
<script>
export default{
    data(){
        return {
            params:{
                "config": {
                    "type": "phone",
                    "before": ,
                    "after": "",
                    "ch": "*"
                },
                "fn": ""
            },
        }
    }
}
</script>

身份证号码脱敏

内置有身份证号码的脱敏类型,脱敏方式是显示前3位和后4位;

<div class="content">
    <input
        v-JDesensitization:params="params"
        placeholder="输入需要脱敏的字符"
        class="input-content"
    />
    <div v-JDesensitization:params="params" class="div-content">
        330621199909091234
    </div>
</div>
<script>
export default{
    data(){
        return {
            params:{
                "config": {
                    "type": "idCard",
                    "before": ,
                    "after": "",
                    "ch": "*"
                },
                "fn": ""
            },
        }
    }
}
</script>

姓名脱敏

内置有姓名的脱敏类型,两个字的姓名脱敏方式是显示第1位;大于两个字的姓名脱敏方式是显示第一个字和最后一个字。

<div class="content">
    <input
        v-JDesensitization:params="params"
        placeholder="输入需要脱敏的字符"
        class="input-content"
    />
    <div v-JDesensitization:params="params" class="div-content">
        张三风
    </div>
</div>
<script>
export default{
    data(){
        return {
            params:{
                "config": {
                    "type": "name",
                    "before": ,
                    "after": "",
                    "ch": "*"
                },
                "fn": ""
            },
        }
    }
}
</script>

邮箱脱敏

内置有邮箱的脱敏类型,脱敏方式是显示第一位和@及以后的字符。

<div class="content">
    <input
        v-JDesensitization:params="params"
        placeholder="输入需要脱敏的字符"
        class="input-content"
    />
    <div v-JDesensitization:params="params" class="div-content">
        123456@163.com
    </div>
</div>
<script>
export default{
    data(){
        return {
            params:{
                "config": {
                    "type": "email",
                    "before": ,
                    "after": "",
                    "ch": "*"
                },
                "fn": ""
            },
        }
    }
}
</script>

自定义脱敏

可以自定义脱敏代替字符,默认为*

修改 config 中的 ch 参数即可自定义脱敏代替字符

params: {
    config: {
        type: "phone",
        before: "",
        after: "",
        ch: "~",
    },
    fn: "",
}

可以自定义脱敏字符头尾显示位数

修改 config 中的 before 和 after 参数即可自定义脱敏显示位数,type 需要修改为内置类型以外的,直接传空即可。

params: {
    config: {
        type: "",
        before: "2",
        after: "2",
        ch: "~",
    },
    fn: "",
}

可以自定义脱敏函数进行脱敏

可以直接在参数的 fn 中传入一个脱敏函数,如果传入了 fn,其优先级最高,则其他参数都不会生效,会直接调用传入的 fn函数 进行脱敏,如:

(str) => {
  return str[0] + '@'.repeat(str.length - 1);
}

应用场景

用户信息填写,输入框聚焦时显示真实数据供用户进行修改,失焦时显示脱敏后的数据

(至于为什么会有这个场景,需要去问一下产品经理)

到此这篇关于基于JavaScript实现一个动态脱敏指令的文章就介绍到这了,更多相关JavaScript动态脱敏指令内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文