前端清理不能替代后端过滤,所有js清洗均可被绕过;submit事件中必须调用event.preventdefault(),否则input.value修改无效;需手动调用form.submit()提交干净数据。

前端清理表单数据不能代替后端过滤,所有 JS 清洗都可被绕过——禁用 JS、curl 提交、抓包重放,后端收到的永远是原始字符串。
submit 事件里必须调用 event.preventDefault()
不加这句,前面所有 input.value = cleaned 都白做。浏览器会忽略你改过的值,照发原始 DOM 数据。
- 常见错误:只绑定
onsubmit="return filter()"却没在函数末尾return false,或忘了event.preventDefault() - 推荐写法:
form.addEventListener('submit', e => { e.preventDefault(); /* 清洗逻辑 */ form.submit(); }) -
form.submit()是手动触发干净数据提交,不是重新走 submit 流程,不会再次触发监听器
input 事件比 keydown 更可靠地捕获非法输入
keydown 拦不住粘贴、拖入、自动填充;change 又太晚(失焦才触发)。只有 input 覆盖全部输入路径。
- 对
<input>和<textarea></textarea>都有效 - 过滤后直接赋值
e.target.value = cleaned,但注意光标跳变:必要时用e.target.setSelectionRange()锁定位置 - 别用
pattern当过滤器——它只校验,不修改、不拦截,用户照样能粘贴<script></script>
hidden 字段不会被 form.reset() 清空
规范明确:reset 行为只作用于“可交互且有初始值”的控件。input[type="hidden"] 没有用户交互态,浏览器直接跳过。
- 清空方式必须手动:
document.querySelectorAll('input[type="hidden"]').forEach(el => el.value = '') - 更稳妥的做法是遍历
form.elements,判断el.type === 'hidden'再赋空值,避免漏掉动态插入项 - 若 hidden 字段由 Vue/React 管理,JS 改 DOM 值不会同步 state,得调用对应 API 或更新响应式数据
全角空格、零宽字符、BOM 不是 trim() 能处理的
String.prototype.trim() 只处理 ASCII 空白符(\t\n\r\f\v 和空格),对 \u200b(零宽空格)、\u00a0(不间断空格)、\ufeff(BOM)完全无效。
- 安全写法:
value.replace(/^[\s\uFEFF\u200B\u00A0]+|[\s\uFEFF\u200B\u00A0]+$/g, '') - 更彻底(需兼容性权衡):
value.replace(/^\p{White_Space}+|\p{White_Space}+$/gu, '')(IE 不支持\p{}) - 富文本或
contenteditable区域要单独处理:textContent或innerText获取后清洗,不能只靠 input.value
最常被忽略的一点:无论你用了多复杂的正则、多及时的 input 监听、多完善的按钮清洗逻辑,只要后端没对 req.body.xxx 做独立清洗,就等于没过滤。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











