前端监控时怎么自动过滤用户输入中的身份证号和手机号?

设计师丽敏 阅读 24

最近在优化前端监控,想在上报用户表单数据前自动过滤身份证号和手机号。我写了正则表达式把中间部分替换成星号,但测试时发现有些正常字段也被误判了,比如某些商品编码格式类似身份证号,导致关键数据被错误覆盖。试过调整正则模式,但效果不好,有没有更稳妥的办法?

比如现在用的身份证过滤代码是这样:


const idRegex = /(d{4})d{10}(d{4})/; // 18位身份证正则
value = value.replace(idRegex, '$1****$2');

但遇到像”商品编号:123456789012345678″(18位纯数字)的字段时,会被错误替换成”12****78″。手机号正则也类似问题,怎么避免这种情况?

另外发现直接替换会影响监控的原始数据完整性,有没有办法在保留原始数据结构的同时,只在上报时动态过滤敏感字段?

我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
长孙淑瑶
前端处理敏感字段,单纯靠正则替换是不够精准的,尤其在你无法确定字段语义的场景,比如商品编码和身份证号长得像。误杀问题很常见,我建议你 **按字段名做白名单匹配 + 正则校验 + 上报前脱敏** 的方式来解决,这样既保留原始数据结构,又能动态过滤敏感信息。

---

### ✅ 正确的思路应该是:

1. **识别字段名**,而不是直接全局替换;
2. 对已知的敏感字段(如 idCardphone)进行正则校验;
3. 只对匹配的字段做脱敏处理;
4. 数据结构保留原始内容,上报时做深拷贝并脱敏。

---

### 🧱 示例代码如下:

// 脱敏配置项
const SENSITIVE_FIELDS = {
idCard: /d{4}d{10}d{4}/,
phone: /1[3-9]d{9}/,
};

// 身份证脱敏函数
function maskIdCard(value) {
return value.replace(/^(d{4})d{10}(d{4})$/, '$1****$2');
}

// 手机号脱敏函数
function maskPhone(value) {
return value.replace(/^1[3-9]d{4}(d{4})$/, '1**** **** $1');
}

// 主处理函数
function maskFormData(data) {
const result = JSON.parse(JSON.stringify(data)); // 深拷贝原始数据

Object.keys(result).forEach(key => {
const value = result[key];

if (SENSITIVE_FIELDS[key]) {
if (SENSITIVE_FIELDS[key].test(value)) {
if (key === 'idCard') {
result[key] = maskIdCard(value);
} else if (key === 'phone') {
result[key] = maskPhone(value);
}
}
}
});

return result;
}


---

### 📦 使用方式:

const formData = {
idCard: '110101199003072316',
phone: '13800138000',
productCode: '110101199003072316' // 不会被误杀
};

const safeData = maskFormData(formData);

console.log(safeData);
// {
// idCard: "1101****2316",
// phone: "1**** **** 2316",
// productCode: "110101199003072316"
// }


---

### 🔍 补充建议:

- 如果你有表单字段命名规范(如以 phoneidCard 等命名),可以用正则去模糊匹配字段名;
- 如果字段名不确定,可以配合注解或 schema 来标记哪些字段是敏感字段;
- 上报日志时不要修改原始数据对象,始终用副本处理;
- 复杂场景下建议引入 schema 校验库(如 YupJoi),结合字段类型和格式做更精细判断。

---

### 💬 小结

别再全量替换了,**按字段判断 + 正则匹配 + 深拷贝上报**才是正解。直接用这个方案可以避免误杀,还能保持原始数据结构不变。
点赞 8
2026-02-03 11:14
Newb.东宸
这个问题确实挺常见的,前端做数据脱敏时很容易误伤正常字段。我的做法是不要单纯依赖正则匹配,而是结合字段名来判断是否需要脱敏。

你可以写一个配置表,指定哪些字段需要脱敏:
const sensitiveFields = ['idCard', 'phone', 'identity'];


然后在上报前遍历数据对象时,只对匹配的字段进行替换:
function maskSensitiveData(data) {
return Object.keys(data).reduce((acc, key) => {
if (sensitiveFields.includes(key)) {
acc[key] = desensitize(data[key], key);
} else {
acc[key] = data[key];
}
return acc;
}, {});
}

function desensitize(value, field) {
if (field === 'idCard' || field === 'identity') {
const idRegex = /(d{4})d{10}(d{4})/;
return value.replace(idRegex, '$1****$2');
} else if (field === 'phone') {
const phoneRegex = /(d{3})d{4}(d{4})/;
return value.replace(phoneRegex, '$1****$2');
}
return value;
}


这样只有明确标注为敏感信息的字段才会被处理,其他类似格式的数据就不会被误判了。

至于保留原始数据结构的问题,可以在上报时生成一份拷贝数据进行脱敏处理,原始数据保持不变:
const originalData = { /* 用户输入 */ };
const maskedData = maskSensitiveData({ ...originalData });

// 上报时用 maskedData
report(maskedData);


这样既能保证监控数据完整性,又不会泄露敏感信息。测试一下这个方法,应该能解决你遇到的问题。
点赞 6
2026-02-02 00:06