submit事件中必须调用preventdefault()并手动调form.submit(),否则前端敏感词过滤无效;正则需动态构造并转义元字符;input事件用于实时体验,submit事件负责兜底;后端仍须重复过滤。

submit 事件里用 replace() 过滤敏感词,但必须 preventDefault()
不调 event.preventDefault(),前端所有过滤都白做——浏览器会照旧提交原始 DOM 值。哪怕你已经把 input.value 改成 "***",只要没阻止默认行为,后端收到的还是用户最初输的脏内容。
常见错误是只改值、不拦提交,或者在 input 事件里过滤却忘了 submit 处理逻辑。
- 监听
form的submit事件,不是click或change - 遍历所有文本类字段(
input[type="text"]、input[type="email"]、textarea),逐个调.value.replace() - 过滤后必须显式调
form.submit(),否则表单不发出 - 别直接改
event.target.elements的引用,要取到具体节点再操作value
敏感词正则得用 new RegExp(word, "g"),不能直接 /word/g
静态正则字面量 /暴力/g 没法拼接变量,一写死就只能过滤固定词;而用户传进来的词库是数组,必须动态构造正则对象。
否则会出现:词库更新了,但正则还是老的;或中文词带 Unicode 转义出错;或大小写不敏感需求无法满足。
- 用
new RegExp(word, "gi")支持忽略大小写(i)和全局替换(g) - word 本身含正则元字符(如
.、*、?)时,得先word.replace(/[.*+?^${}()|[]\]/g, '\$&')转义,否则报错或漏匹配 - 多个词串联时,别用
|拼一个大正则——词里有括号或竖线会崩,逐个循环更稳
input 事件实时过滤 vs submit 事件最终清洗,选哪个?
两者不是二选一,而是分层配合:input 事件负责体验(比如粘贴后立刻删掉“色情”二字),submit 事件负责兜底(防止禁用 JS 或绕过前端校验)。
只做 input 过滤,用户能用 DevTools 改 DOM 后直接点提交;只做 submit 过滤,用户看不到实时反馈,体验割裂。
-
input事件覆盖粘贴、拖入、自动填充等全部输入路径,比keydown可靠 - 实时过滤后光标容易跳到末尾,需用
e.target.setSelectionRange(oldStart, oldEnd)保持位置(简单场景可省) -
submit过滤必须存在,且逻辑要比input更严格(比如多词重叠时全替,不依赖用户是否已看到提示) - 后端仍要重复过滤——前端任何正则都能被 curl、Postman 或禁用 JS 绕过
为什么 pattern 属性对敏感词过滤完全无效?
pattern 是表单验证属性,只参与 reportValidity() 和原生提交校验,它既不修改 value,也不拦截输入,更不支持自定义替换逻辑。
用户粘贴“暴力色情违禁品”,pattern="[a-z]+" 根本不触发,照样能点提交;就算弹红框,值也没变,后端照收原样。
-
pattern不支持 Unicode 简写(如p{Han}),中文得写[u4e00-u9fa5] - 它只在提交时检查是否“匹配”,不是“过滤”——匹配失败就阻断,但不会帮你把“暴力”换成“***”
- 移动端 pattern 可能影响键盘类型,但和内容安全毫无关系,别误以为加了就防住了
真正难的是词库维护和边界 case:比如“色”单独出现是否违规,“颜色”的“色”要不要放过,还有“暴力机构”和“暴力美学”怎么区分。正则做不到语义理解,这类问题得靠分词 + 词性 + 上下文,前端 JavaScript 扛不住,得交到后端 NLP 模块处理。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











