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

表单必须包裹在 <form></form> 里,不能只塞进 <td>
<p>很多人以为把 <code><input> 往 <td> 里一丢就完事了,结果点提交啥也没发出去。根本原因是:浏览器只提交**被 <code><form></form> 直接或间接包裹**的控件。单独放在 <td> 里的 <code><input>,哪怕有 name,也不会进提交数据。
正确做法是整个表格(或部分行)包在 <form></form> 内,或者用 HTML5 的 form 属性把分散的控件“认领”回来。
-
<form></form>必须设method和action,否则提交会失败或跳转空白页 - 所有要提交的
<input>、<select></select>、<textarea></textarea>都得有name属性,id不管用 - 如果表格里有多组独立操作(比如每行一个“删除”按钮),别硬塞进同一个
<form></form>,改用form="form-id"属性绑定到对应<form></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> 里再嵌一层 <code><table>,然后往子表格里塞 <code><input>,只要没把整个子表格包进 <form></form>,或者 <form></form> 被写在错位置(比如包在 <tr> 里),就会出问题。
<p>典型症状:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5806" title="html-deploy"><img
src="https://img.php.cn/upload/skill/000/000/081/179066538882434.jpg" alt="html-deploy" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5806" title="html-deploy" class="overflowclass">html-deploy</a>
<p class="overflowclass">使用 htmlcode.fun 将 HTML 内容或文件部署到网页,适用于用户要求“部署到网页”“托管此 HTML”“生成此前端...的实时链接”等场景。</p>
</div>
<a rel="nofollow" href="/xiazai/skill5806" title="html-deploy" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>提交后只有主表数据,子表格输入框的值全丢了</li>
<li>Chrome DevTools 里能看到 <code><input>,但 FormData(this) 里没有它
<form></form> 放在 <tr> 内——浏览器会自动把它挪到表格外面,DOM 结构已不是你写的那样
<p>安全做法:把 <code><form></form> 放在最外层 <table> 外,或至少确保它包裹了所有目标 <code><td>;子表格只是视觉容器,不参与表单层级。
<h3>用 <code>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></form> 的作用域边界——它看不见 <td> 之外的控件,也管不了被浏览器“修正”到外部的节点。结构对了,<code>name 对了,FormData 才能拿到东西。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










