后端收不到字段值通常因误用disabled而非readonly——disabled会阻止字段值进入请求体,readonly则保留值提交;仅text、password、email、textarea支持readonly,select等控件需替代方案。

后端收不到字段值?八成是把 readonly 写成了 disabled——这不是样式问题,是值进不进请求体的根本分水岭。
表单提交时字段值会不会发到后端
这是唯一不可妥协的判断依据。用 disabled,浏览器在构造 FormData、执行 form.serialize() 或原生 form.submit() 时,会直接过滤掉整个控件的 name 和 value;而 readonly 控件的值照常参与序列化,后端可通过 request.getParameter("id") 正常取到。
常见翻车现场:<input name="order_id" value="1001" disabled> → 后端日志查无 order_id 字段,接口报“缺少必传参数”。
- 用户要看到、要复制、后端还必须收到?→ 用
readonly - 只是临时锁死、且不希望它进请求?→ 用
disabled - 千万别同时写
readonly和disabled——disabled优先级更高,readonly形同虚设
readonly 哪些元素支持,哪些写了也白加
readonly 不是万能锁,它只对可编辑文本类控件生效:<input type="text">、<input type="password">、<input type="email">、<textarea></textarea>。其他控件加了也白加:
-
<select readonly></select>→ 浏览器直接忽略,下拉框仍可点选 -
<input type="checkbox" readonly>→ 无法阻止勾选/取消 -
<button readonly></button>→ 完全无效,按钮照点
替代方案:
-
<select></select>只读需求:改用<input type="text" readonly value="选项A">模拟,或 JS 控制每个<option disabled></option> -
<input type="checkbox">需视觉只读但保留值:用disabled+ 同名<input type="hidden">补值
JS 动态控制 readonly 和 disabled 的坑
静态写 HTML 很直观,但 JS 切换状态容易出兼容性问题:
- 设
disabled:安全写法是el.disabled = true或el.disabled = false;避免用setAttribute('disabled', ''),移除时还得额外removeAttribute('disabled') - 设
readonly:别用el.readOnly = false(旧版 Safari 不响应);稳妥做法是禁用时el.setAttribute('readonly', ''),启用时el.removeAttribute('readonly') - 判断状态别用
getAttribute("readonly")(返回null或字符串),应始终用el.readOnly(注意大小写)布尔值
聚焦、复制、可访问性差异不是体验优化,而是功能刚需
这直接影响可用性:
-
readonly允许:Tab 切入、鼠标点击聚焦、.focus()、双击选中、Ctrl+A、Ctrl+C;也支持监听focus事件 -
disabled彻底阻断:Tab 跳过、.focus()静默失败、无法选中或复制;:focus伪类不触发,outline也不显示 - 展示 API Key、调试 ID、金额等需复制的字段,必须用
readonly;用disabled用户点不动、选不了、也复制不了 -
readonly默认无视觉变化(看起来完全可编辑),实际项目中几乎总要配 CSS:input[readonly] { background-color: #f5f5f5; cursor: default; }
真正容易被忽略的是:表单状态切换时,焦点管理没跟上;还有,某些 UI 库(比如 Ant Design 的 Input)把 readOnly 属性映射为 readonly,但文档没强调它不影响提交——结果开发在表单里用了 readOnly={true},测试时才发现后端少收了一个字段。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











