表单必须包裹在<form>内,否则<input>等控件不会提交;所有控件需有name属性;多行数据用rows0等数组语法命名;<form>应置于<table>外或完整包裹目标单元格;推荐使用FormData提交。

表单必须包裹在 <form> 里,不能只塞进 <td>
很多人以为把 <input> 往 <td> 里一丢就完事了,结果点提交啥也没发出去。根本原因是:浏览器只提交**被 <form> 直接或间接包裹**的控件。单独放在 <td> 里的 <input>,哪怕有 name,也不会进提交数据。
正确做法是整个表格(或部分行)包在 <form> 内,或者用 HTML5 的 form 属性把分散的控件“认领”回来。
-
<form>必须设method和action,否则提交会失败或跳转空白页 - 所有要提交的
<input>、<select>、<textarea>都得有name属性,id不管用 - 如果表格里有多组独立操作(比如每行一个“删除”按钮),别硬塞进同一个
<form>,改用form="form-id"属性绑定到对应<form>
name 属性怎么写才能让后端收到数组结构?
表格常有多行同类数据,比如“商品列表”,后端希望收成数组。靠手写 name="item1"、name="item2" 不可扩展,也难解析。要用 PHP 或其他后端能识别的数组语法。
示例中每行两个字段,后端拿到的是 $_POST['rows'][0]['name'] 和 $_POST['rows'][0]['price']:
立即学习“前端免费学习笔记(深入)”;
<tr> <td><input type="text" name="rows[0][name]" value="苹果"></td> <td><input type="number" name="rows[0][price]" value="5.5"></td> </tr> <tr> <td><input type="text" name="rows[1][name]" value="香蕉"></td> <td><input type="number" name="rows[1][price]" value="3.2"></td> </tr>
- 方括号语法
rows[0][name]是通用约定,PHP、Python Flask、Node.js body-parser 都支持解析 - 索引用数字更稳妥,避免用字符串键(如
rows[first][name])导致某些后端解析失败 - JavaScript 动态增删行时,注意同步更新
name中的索引,否则后端收到空项或覆盖
嵌套表格里放表单,DOM 结构容易崩
如果在 <td> 里再嵌一层 <table>,然后往子表格里塞 <input>,只要没把整个子表格包进 <form>,或者 <form> 被写在错位置(比如包在 <tr> 里),就会出问题。
典型症状:
- 提交后只有主表数据,子表格输入框的值全丢了
- Chrome DevTools 里能看到
<input>,但FormData(this)里没有它 - 把
<form>放在<tr>内——浏览器会自动把它挪到表格外面,DOM 结构已不是你写的那样
安全做法:把 <form> 放在最外层 <table> 外,或至少确保它包裹了所有目标 <td>;子表格只是视觉容器,不参与表单层级。
用 FormData 提交比手动拼 JSON 更可靠
直接 fetch + FormData 是目前最省心的提交方式,尤其含文件或空值时。
别这么写(容易漏、编码错、不兼容文件):
fetch('/save', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ name: input.value })
});
应该这么写:
document.querySelector('form').addEventListener('submit', e => {
e.preventDefault();
const fd = new FormData(e.target); // 自动收集所有带 name 的控件
fetch('/save', { method: 'POST', body: fd });
});
-
FormData会自动处理文件上传、空值过滤、编码转换,不用你操心 - 服务器端(如 PHP)直接用
$_POST和$_FILES接收,和传统表单提交行为一致 - 如果后端要求 JSON 格式,再用
Object.fromEntries(fd)转,但多数 REST API 已支持multipart/form-data
真正容易被忽略的,是 <form> 的作用域边界——它看不见 <td> 之外的控件,也管不了被浏览器“修正”到外部的节点。结构对了,name 对了,FormData 才能拿到东西。



















