先记住这个答案
readonly 用于“值已确定但仍要展示和提交”的控件:用户不能改,但一般可聚焦、可复制,提交时仍包含该字段。disabled 表示控件当前不可用,通常不能聚焦,并且不会随表单提交。readonly 只适用于支持它的文本类或部分日期时间输入及 <textarea>,不能直接拿来让 <select> 只读。
readonly值通常仍会提交disabled控件不提交readonly适用于部分输入和文本区<select>没有原生readonly
订单编号需要展示还是排除
如果订单编号由服务端生成,只想在页面上显示,纯文本往往更清楚。若业务确实要在表单里保留它,readonly 可以让用户看见但不能在普通交互中改动;若用 disabled,提交时就不会包含该字段。
<label>订单编号
<input name="orderId" value="A1024" readonly>
</label>
<label>暂不可选的优惠码
<input name="coupon" value="" disabled>
</label>提交时前一个字段通常会带上 orderId=A1024,后一个禁用字段不会进入成功控件集合。界面上两者可能都呈灰色,但语义和数据流不同。
即使 readonly 值会被提交,服务端也不能相信它。用户可以通过开发者工具改 DOM 或直接发送请求;订单编号等关键值必须在服务端与会话数据核对。
支持范围与校验
readonly 不是所有控件通用的“锁”。单选、复选、滑块和 <select> 等不适合靠它阻止选择;应根据需求选择 disabled、纯文本展示或自定义交互方案。
禁用字段退出约束校验;只读字段也不按普通可编辑字段处理必填约束。若业务要求用户确认某项信息,光把控件设为只读或禁用不能算作完成确认,应提供独立的确认操作。
一个常见例子是订单编号:让用户看见但不改,可以用只读文本框;若只是展示信息而不需要继续提交,普通文本可能更合适。禁用字段不会进入正常表单提交,服务器无法依赖它回传原值;只读值虽然会发送,也不能成为权限或价格的依据。readonly 主要适用于可编辑文本类控件,复选框和下拉框并没有等价的只读状态,不能把它们简单写成 readonly 就期待浏览器阻止修改。
容易答错的地方
- 用
disabled保留提交值 - 禁用控件不会正常提交。若服务端需要该信息,应从可信状态取值,而不是依赖禁用字段。
- 给
<select>写readonly <select>没有原生只读模式。需要展示当前选择但禁止更改时,考虑禁用控件并在服务端保留值,或直接显示文本。
面试官还会怎么问?
只读输入还能复制内容吗?
通常可以聚焦并选择复制,这也是它与禁用控件的一个交互差异。
隐藏输入能替代禁用字段提交吗?
技术上可以传值,但隐藏值仍可被篡改,服务端不能把它当成可信来源。
required 放在只读字段上有意义吗?
只读字段不能由用户填写,通常不会按普通必填字段参与约束校验;应重新设计数据来源与确认流程。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。