readonly不能防篡改,仅防键盘输入和删除;仅对text、password、email、tel、url、search、date、number类input及textarea生效;checkbox、hidden、select等无效;混用disabled会导致字段不提交;后端必须校验。

readonly 属性本身不能防止用户修改——它只阻止键盘输入和删除,对粘贴、拖拽、JS 赋值、开发者工具删属性等行为完全无效。真正能“防止修改”的只有后端校验,readonly 只是前端交互层的友好提示。
哪些 input 类型加 readonly 才真正生效
只对两类元素起作用:<input>(限 text、password、email、tel、url、search、date、number 等文本类)和 <textarea></textarea>。
以下写法等于白写,浏览器直接忽略:
<input type="checkbox" readonly><input type="hidden" readonly><select readonly></select><button readonly></button>
readonly 和 disabled 混用会丢字段值
如果同时写 readonly 和 disabled,disabled 会完全压制 readonly:字段既不可编辑,也不会出现在 FormData、serializeArray() 或表单提交参数中。
典型后果:
- 订单号字段误加
disabled,后端收不到order_id,校验失败 - 用户 ID 字段用了
disabled,接口返回 400 或空指针异常 - 表单验证逻辑依赖该字段存在,但实际请求里根本没它
记住一个判断标准:这个值后端要不要校验?要 → 必须用 readonly;不要 → 才考虑 disabled。
JavaScript 动态控制 readonly 的坑
原生 JS 设置时,大小写和方法选择直接影响兼容性:
- 设为只读:
el.setAttribute("readonly", "readonly")或el.readOnly = true(注意是readOnly,不是readonly) - 恢复可编辑:
el.removeAttribute("readonly")(比el.readOnly = false更可靠,尤其在 Safari 15 及更早版本) - React 中必须写
readOnly={isLocked}(驼峰拼写,写成readonly就失效) - Vue 中绑定
:readonly="isLocked"可行,但需确保isLocked是响应式数据且初始值准确
最常被忽略的一点:readonly 字段的值仍会随表单提交,而用户只要打开开发者工具删掉该属性,就能任意修改并提交——这是设计使然,不是漏洞。所以后端必须校验该字段是否与原始值一致,比如比对数据库快照、时间戳或签名,否则前端限制毫无业务意义。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











