HTML中多选下拉框的name属性不必强制带[]后缀,浏览器原生提交时均以同名参数重复发送(如tag_ids=1&tag_ids=2),是否解析为数组取决于后端框架配置;加[]仅为PHP等框架的语义约定,并非HTML标准要求。

HTML中多选下拉框的name属性必须带[]后缀
浏览器原生表单提交时,<select multiple> 的多个选中值不会自动组成数组——它只取决于服务端如何解析。但约定俗成的做法是给 name 加上 [],比如 name="tag_ids[]",这样 PHP、Node.js(用 body-parser)、Django 等主流后端框架才能识别为数组。不加 [] 时,多数后端只取最后一个选中项。
- PHP:直接用
$_POST['tag_ids']得到数组(前提是 name 带[]) - Express +
body-parser:需启用extended: true,否则req.body.tag_ids是字符串而非数组 - Flask:用
request.form.getlist('tag_ids'),不依赖 name 是否带[],但加了更语义清晰
纯前端 JS 提交时注意 FormData 的 append 行为
如果用 fetch 或 XMLHttpRequest 手动构造数据,别直接传 JavaScript 数组给 FormData.append()——它会调用 .toString(),把 [1,2,3] 变成 "1,2,3"。正确做法是循环逐个 append:
const selects = Array.from(document.querySelectorAll('select[multiple] option:checked'));
const formData = new FormData();
selects.forEach(opt => {
formData.append('tag_ids', opt.value); // 注意:这里不用 [],浏览器自动聚合同名字段
});
关键点:FormData 对同名键多次 append,后端收到的就是数组(只要后端解析逻辑支持);而 append('tag_ids[]', ...) 是无效写法,方括号对 FormData 没意义。
checkbox 组传数组的 name 写法和 select 一致
多个 <input type="checkbox"> 共享同一 name(如 name="roles"),且至少一个被勾选,提交后该 name 就会作为数组传递。是否加 [] 取决于后端习惯——PHP 强烈建议写 name="roles[]",而 Node.js 的 body-parser 在 extended: true 下对 name="roles" 和 name="roles[]" 都能正确解析为数组。
立即学习“前端免费学习笔记(深入)”;
- 未勾选任何 checkbox 时,该 name 完全不会出现在表单数据中(不是空数组)
- 想确保后端收到空数组,需额外加一个
disabled的隐藏 input:<input type="hidden" name="roles[]" value="">,但要注意它可能干扰业务逻辑 - 避免混用
name="roles"和name="roles[]"在同一表单里,不同浏览器对重复 name 的序列化行为略有差异
后端接收不到数组?先检查 Content-Type 和解析配置
常见错误不是前端写错,而是后端没配好解析器。例如 Express 默认的 body-parser.urlencoded() 若没设 { extended: true },遇到 name="tags[]" 会把整个值当字符串解析,导致 req.body.tags 是 "1,2,3" 而非 [1,2,3]。
- PHP:确认
php.ini中max_input_vars足够大,否则超量选项会被截断 - Node.js:用
body-parser@1.20+,旧版对嵌套数组支持不稳 - Nginx:若启用了反向代理,检查是否截断了长查询参数(尤其 GET 提交多选)
最稳妥的验证方式:在后端打印原始请求体(raw body)或查看 req.headers['content-type'],确认是不是 application/x-www-form-urlencoded 或 multipart/form-data,再对应检查解析逻辑。数组传递本身很简单,难的是两端约定一致。



















