SELECT 标签必须有 name 属性才能提交数据,否则后端收不到值;OPTION 的 value 决定提交内容,与显示文本可不同;禁用应使用 disabled 而非 readonly;默认选中用 selected 属性。

SELECT 标签必须有 name 属性才能提交数据
表单里 SELECT 如果没加 name,用户选了也没用——提交时整个字段直接被忽略。后端收不到值,前端 JavaScript 用 formdata.get() 也取不到。
常见错误是只写 <select id="city">,却漏掉 name="city"。哪怕你用 id 做 DOM 操作,提交行为仍依赖 name。
-
name值要和后端约定好(比如后端期待category,你就不能写成cat) - 多个
SELECT共享同一个name(如多选场景),需加multiple属性,否则只提交最后一个选中的值 - 如果只是做 UI 交互、不参与表单提交,
name可省,但得靠id或其他方式绑定 JS 逻辑
OPTION 的 value 和文本内容不是一回事
用户看到的是 OPTION 标签里的文字(比如“北京”),但表单实际提交的是 value 属性的值。两者可以不同,而且经常应该不同。
比如地区下拉中显示“广东省”,但后端更希望接收 value="gd" 或 value="440000" 这类简写或编码,而不是中文字符串——避免编码、空格、全角半角等问题。
- 没写
value的OPTION,提交时会把标签内文本作为值(可能含空格或换行,引发解析失败) -
value推荐用 ASCII 字符,避免 URL 编码麻烦;中文或特殊符号务必手动 urlencode(但不如一开始就避开) - 禁用选项用
disabled,不要靠隐藏OPTION或 JS 阻止选择——它仍可能被绕过提交
设置默认选中项:selected vs. defaultSelected
让某个 OPTION 加载即被选中,用 selected 属性就行。注意它是个布尔属性,写上就生效,不用赋值:<option selected>上海</option>。
别混淆 defaultSelected ——那是 JavaScript 的只读属性,表示 HTML 中原始是否带 selected,不能用来设初始状态。
- 一个
SELECT中只能有一个selected(多选除外),浏览器会自动忽略后续的selected - 动态渲染(如 Vue/React)时,别在模板里硬写
selected,应通过绑定v-model或value控制选中态 - 服务端渲染时,如果默认值来自数据库,确保
selected准确落在对应OPTION上,别因模板循环错位
禁用整个下拉框:用 disabled,别用 readonly
SELECT 不支持 readonly 属性,写了也无效。想让它不可操作且不提交值,唯一标准做法是加 disabled。
加了 disabled 后,该字段不会出现在表单序列化结果里(FormData、serialize()、submit 请求体均不含它),这点和 INPUT 一致。
- 若需“视觉禁用但保留提交”,改用
pointer-events: none+opacity: 0.6等 CSS,同时保持disabled移除——但这属于 hack,慎用 - JS 动态启用/禁用,直接操作
element.disabled = true/false,别试图删增disabled属性 - 移动端 Safari 对
disabled SELECT的样式支持较弱,建议补一句select:disabled { background: #eee; }
value 当显示文本用、漏写 name、以及在框架中误用原生 selected 属性覆盖响应式绑定。


















