错误。readonly值照常提交,disabled值完全不提交;前者可聚焦、复制,后者不可交互且被表单序列化彻底过滤。

readonly 和 disabled 都不提交,但行为完全不同
很多人以为 readonly 和 disabled 都只是“不让改”,其实它们对表单提交的影响一致(都不提交),但底层机制和交互表现差异极大。关键区别在于:前者仍参与表单提交流程、能被聚焦、可复制;后者完全脱离表单控件生命周期、无法聚焦、值不会出现在 FormData 或 serialize() 结果里——哪怕你手动给 disabled 元素赋了值,它也不会进提交数据。
什么时候该用 readonly 而不是 disabled
典型场景是展示 + 保留原始值供后端校验或日志记录。比如订单详情页的 order_id 字段,用户不能改,但必须随表单一起提交。此时用 readonly 更稳妥:
-
readonly元素仍会出现在document.querySelectorAll('input:not([disabled])')的结果中 -
readonly输入框支持鼠标选中、Ctrl+C 复制,对用户更友好 - 某些前端框架(如 Vue)在响应式绑定时,
disabled可能触发意外的 watch 停止或 computed 缓存失效,而readonly不干扰响应链 - 若字段需参与客户端校验(比如用
required配合readonly),浏览器会跳过必填检查,但值依然存在——这比disabled彻底“消失”更可控
disabled 在提交前临时启用的坑
常见错误是想“临时放开 disabled 字段再提交”,比如:el.disabled = false; form.submit();。问题在于:
- 如果表单用了
event.preventDefault()+fetch,disabled字段的值根本不会被new FormData(form)收集,即使你刚设成false - DOM 更新是异步的,
disabled = false后立即读取FormData,可能仍拿不到值(尤其在 React 或 Vue 的批量更新周期内) - 更可靠的做法是:用
readonly替代,或提交前 clone 表单节点并移除disabled属性,而非动态切换
React/Vue 中绕过 disabled 提交的常见误操作
框架里直接操作 DOM 属性容易失效。例如 Vue 模板中写 <input :disabled="isLocked">,然后 JS 里执行 el.disabled = false,很可能被下一次响应式更新覆盖。正确做法是:
- 把是否禁用的状态收归到组件 data / reactive 对象里,统一控制
- 需要提交时,改用
readonly+ 手动把值塞进FormData或请求 payload - 避免混合使用
v-model和原生disabled,Vue 会忽略绑定,导致视图与数据不同步
disabled 字段不仅不提交,还会被浏览器忽略其 name 属性——哪怕你在 HTML 里写了 name="user_email",只要加了 disabled,它就不会出现在任何标准序列化结果里。这点在调试接口参数缺失时,特别容易卡住。

















