权限校验必须在submit事件中通过preventdefault后、请求前执行,且需基于缓存的userpermissions数组与data-required-permission值严格匹配;失败时须提示用户,禁用按钮不可信,服务端校验为最终防线。

表单提交前必须校验权限,不能只靠禁用按钮
禁用按钮(disabled)只是视觉和交互层面的限制,用户删掉这个属性、或者用 DevTools 临时启用,就能照常提交。真正起作用的拦截点只有一个:表单的 submit 事件。
权限校验必须在 event.preventDefault() 之后、实际发送请求之前执行。哪怕按钮已 disabled,也要重复校验——因为 JS 层面的控制才是唯一可信的防线。
- 后端返回的权限数据应缓存在前端(如
userPermissions数组),避免每次提交都查接口 - 权限标识建议统一用字符串,比如
"create-post"、"delete-user",和表单的data-required-permission值严格匹配 - 校验失败时,不要静默吞掉提交,而要
alert("无此操作权限")或显示 Toast,否则用户会以为“点了没反应”
用 data-* 属性声明权限要求,解耦 HTML 与逻辑
在 form 标签上加一个自描述的属性,比如 data-required-permission="update-post",比把权限逻辑硬写进 JS 更易维护、更易测试。
这样做的好处是:模板可读性强,后端渲染时也能动态注入权限字段,且不依赖 JS 就能被自动化工具扫描出权限缺口。
- 多个权限用空格分隔:
data-required-permission="read-post update-post" - 支持“或”逻辑:只要满足其中一个即可;如需“且”,改用数组校验并用
every() - 避免用
id或class存权限,它们语义不清,且易被样式或框架误操作覆盖
监听 submit 事件并手动控制流程
别信浏览器默认行为。所有表单提交都必须显式调用 e.preventDefault(),否则页面可能跳转、刷新,JS 校验直接失效。
校验通过后,有两种后续路径:一是用 fetch 手动发请求,二是恢复原生提交(仅限简单场景)。前者可控性高,后者需确保 action 和 method 正确无误。
- 用
form.requestSubmit()触发原生验证(如required字段)后再拦截,比直接绑click更可靠 - 若用
fetch,记得手动收集表单数据:new FormData(form),它自动忽略disabled字段 - 不要在
submit回调里直接form.submit(),这会绕过所有 JS 控制,形成死循环
隐藏字段和权限校验容易漏掉的坑
表单里如果有隐藏字段(比如 <input type="hidden" name="role" value="admin">),它虽不展示,但依然参与提交。如果这个值被用户篡改,又没在 JS 层复核,权限校验就形同虚设。
更危险的是 required + hidden 组合:浏览器无法聚焦隐藏元素,验证失败时行为不一致(Safari 可能报错,Chrome 可能静默失败),必须移除 required,全权交由 JS 校验。
- 敏感字段(如角色、状态、来源标记)应在提交前用 JS 二次确认其值是否合法,而非信任 DOM 初始值
- 权限校验函数应独立封装,避免散落在各个
submit监听器里,方便单元测试和复用 - 服务端永远要做最终校验——前端拦截只是提升体验,不是安全边界
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











