radio单选框必须同名才能互斥且被提交;name不同则后端收不到该字段;需确保至少一个被用户手动选中、value语义明确、用label包裹提升可访问性,并在后端校验字段是否存在。

radio单选框必须有相同的name才能互斥
浏览器只把「同名且被选中」的input type="radio"值发给后端。如果每个radio的name都不同,提交时一个都不会传——看着选了,实际POST体里是空的。
常见错误写法:
<input type="radio" name="gender1" value="male"> 男<br> <input type="radio" name="gender2" value="female"> 女
这样两个
name不一致,后端收不到gender字段。
正确写法示例:
<form method="POST" action="/submit"> <input type="radio" name="gender" value="male"> 男<br> <input type="radio" name="gender" value="female"> 女<br> <input type="radio" name="gender" value="other"> 其他<br> <button type="submit">提交</button> </form>
注意:value值要写清楚,别留空或全用"on"——那是默认值,语义丢失,后端难处理。
表单method="POST"本身不保证数据发送成功
POST只是告诉浏览器“用HTTP POST方法发”,但真正能发出数据,还得满足三个条件:
立即学习“前端免费学习笔记(深入)”;
-
form标签必须有action属性(哪怕只是action="#"用于前端调试) - 至少有一个
radio被用户手动点选(未选中时,该name完全不会出现在POST数据里) - 不能靠
checked属性“假装已选”——如果用户没点过,且没设checked,那整个字段就不存在于请求中
调试建议:提交后立刻看浏览器开发者工具的Network → Form Data栏。如果看不到gender这一行,说明没选、name不统一,或被JS拦截了提交。
后端接收时要注意radio没有“未选中”值
和checkbox不同,radio组在用户未做任何选择时,POST请求里压根不包含这个字段名。PHP收到的是$_POST['gender']未定义;Node.js的req.body.gender是undefined;Python Flask里request.form.get('gender')返回None。
所以后端不能直接解构或强转,得先判断是否存在:
// Node.js Express 示例<br>
if (!req.body.gender) {<br>
return res.status(400).send('请选择性别');<br>
}
也别依赖required属性做唯一校验——它只触发浏览器前端提示,禁用JS或绕过表单就能跳过。服务端必须自己校验。
移动端或无障碍场景下label包裹很重要
单纯写<input type="radio" name="theme" value="dark"> 暗色,在iOS Safari或屏幕阅读器里可能无法点击文字区域触发选择,导致用户实际无法选中,进而POST无数据。
务必用label显式关联:
<label><br> <input type="radio" name="theme" value="light"> 亮色<br> </label><br> <label><br> <input type="radio" name="theme" value="dark"> 暗色<br> </label>
或者用for/id配对(效果等价):
<input id="theme-light" type="radio" name="theme" value="light"><br> <label for="theme-light">亮色</label>
这不只是体验问题,而是直接影响「能否选中」,最终决定POST里有没有这个字段。
容易被忽略的一点:多个radio组混在同一表单时,只要name不同,它们之间完全独立;但一旦name相同,哪怕分散在不同fieldset里,也会强制互斥——这是HTML规范行为,不是bug。



















