在 form.on('submit') 中修改 password 字段值:先取明文密码,用 RSA 加密后写入隐藏域(如 encrypted_password),再清空原始 password 输入框;身份证/手机号则用正则脱敏后通过 $.ajax 手动提交。
form.on('submit') 里怎么改 password 字段值
提交前把明文密码替换成密文,是前端脱敏最常见场景。layui 的 form.on('submit()') 是唯一可靠拦截点,别指望在 input 失焦或按钮点击时处理——那些时机无法保证最终提交值被修改。
关键动作只有两步:取值 → 加密 → 写回表单域(通常是隐藏域)→ 清空原始 password 输入框。
- 必须提前引入
JSEncrypt或其他 RSA 库,公钥要和服务端约定一致,不能硬编码在前端源码里 - 加密后写入的字段名(如
encrypted_password)要和服务端接收参数名完全匹配 -
$('#password').val('')这一步不能省,否则 Layui 提交时仍会把空字符串或原始值发过去 - 如果用了 Layui 的
lay-verify校验,注意校验发生在 submit 拦截之前,所以明文密码仍需通过长度、格式等基础校验
身份证/手机号字段怎么在提交前脱敏再传给后端
不是所有敏感字段都需要加密,比如身份证号、手机号,后端往往只要脱敏后的展示值(如 110101****1234),而非加密密文。这时候用正则替换最直接。
在 form.on('submit()') 回调里对对应字段做处理:
var data = $('#your-form').serializeObject(); // 假设你有这个工具方法
data.id_card = (data.id_card || '').replace(/^(.{6})(?:\d+)(.{4})$/, '$1****$2');
data.phone = (data.phone || '').replace(/^(.{3})(?:\d+)(.{4})$/, '$1****$2');
然后用 $.ajax 手动提交,绕过 Layui 默认的 form action 提交逻辑。因为 Layui 的原生 submit 会按 DOM 顺序取值,不走你改过的 data 对象。
- 别用
$('#id_card').val(...)直接改输入框值——会影响用户二次编辑,且 lay-verify 可能报错 - 正则里的
.*要换成\d+或\w+,避免误替换非数字字符 - 如果字段可能为空或 null,一定要先兜底:
data.id_card || '',否则.replace会报错
为什么不能只改页面显示值,而要改提交数据本身
很多人以为用 templet 或 Vue 的 v-model 做显示层脱敏就够了,但提交时浏览器仍会读取原始 input.value。Layui 的 form.on('submit()') 拿到的 data.field 就是 DOM 当前值,不是你模板里渲染的脱敏串。
-
templet只影响表格列渲染,对表单提交无任何作用 - 用
v-if切换 input 和 p 标签,只是 UI 层遮盖,input元素依然存在且值未变 - 哪怕加了
type="password",提交时还是明文——这只是浏览器渲染行为,不影响实际传输内容 - 真正起效的,只有在 submit 拦截里手动干预
data.field或改 DOM value,或彻底接管提交逻辑
容易忽略的密钥与协同问题
前端加密不是“套个函数就完事”。RSA 公钥若由后端动态下发,就得在 submit 前发起一次异步请求获取密钥——这意味着 submit 必须阻塞等待,否则加密会失败。而 Layui 的 form.on('submit()') 默认同步执行,不支持 await。
- 要么把密钥缓存到 localStorage(注意有效期和更新机制)
- 要么改用同步加密算法(如 AES,但密钥管理更复杂)
- 最稳妥的方式是:前端只做脱敏(掩码),加密交给后端——前端传脱敏后字符串 + 原始明文(放 hidden input 并设
name为服务端可识别的标记),由后端决定是否加密存储 - 如果后端要求必须前端加密,那密钥轮换、失效、错误提示(如公钥加载失败)都得有 fallback,不能让整个表单卡死
脱敏逻辑本身很简单,难的是密钥怎么管、错误怎么兜、前后端字段怎么对齐——这些细节漏一个,上线后就是生产事故。


















