如何通过JavaScript XHR将表单输入值绑定到API POST请求?
表单数据映射到API请求对象的实现方案
一、表单输入框的name属性设置规则
1. 顶层字段(如Key、Remark)
直接使用API字段名作为输入框的name,比如:
<input name="Key" type="text" placeholder="请输入Key"> <textarea name="Remark" placeholder="请输入备注"></textarea>
2. 嵌套数组SODTL的字段
根据数组项是固定数量还是可动态增删,分两种命名方式:
- 固定数量的数组项:用
SODTL[索引].字段名的格式,明确对应数组的第N项。比如第一个明细项的字段:<!-- 第一个SODTL项 --> <input name="SODTL[0].Dtl" type="text" placeholder="明细内容"> <input name="SODTL[0].Code" type="text" placeholder="编码"> <!-- 第二个SODTL项 --> <input name="SODTL[1].Dtl" type="text" placeholder="明细内容"> <input name="SODTL[1].Code" type="text" placeholder="编码"> - 可动态增删的数组项:推荐用
SODTL[].字段名或者SODTL[][字段名]的格式,前者适合手动遍历行收集数据,后者兼容FormData的批量取值逻辑。示例:<!-- 动态行的输入框 --> <div class="sodtl-row"> <input name="SODTL[].Dtl" type="text" placeholder="明细内容"> <input name="SODTL[].Code" type="text" placeholder="编码"> </div>
二、JavaScript收集表单数据并构造请求对象
假设你的目标请求对象结构如下:
const targetPostObj = { Key: "", Remark: "", SODTL: [ { Dtl: "", Code: "" }, // 更多明细项... ] };
1. 固定数组项的场景
直接按索引读取对应输入框的值,构造数组:
// 获取表单元素 const form = document.getElementById("your-form-id"); // 构造请求对象 const postObj = { // 读取顶层字段 Key: form.elements["Key"].value.trim(), Remark: form.elements["Remark"].value.trim(), SODTL: [] }; // 循环收集固定数量的SODTL项(假设最多2项) for (let i = 0; i < 2; i++) { const dtlVal = form.elements[`SODTL[${i}].Dtl`].value.trim(); const codeVal = form.elements[`SODTL[${i}].Code`].value.trim(); // 可选:仅当有值时加入数组(避免空对象) if (dtlVal || codeVal) { postObj.SODTL.push({ Dtl: dtlVal, Code: codeVal }); } } // 后续用XHR发送请求 const xhr = new XMLHttpRequest(); xhr.open("POST", "你的API地址", true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { console.log("请求成功", xhr.responseText); } else { console.error("请求失败", xhr.statusText); } }; xhr.send(JSON.stringify(postObj));
2. 动态增删数组项的场景
先实现行的增删逻辑,再遍历所有行收集数据:
第一步:HTML与增删行JS
<form id="your-form-id"> <!-- 顶层字段 --> <input name="Key" type="text" placeholder="请输入Key"> <textarea name="Remark" placeholder="请输入备注"></textarea> <!-- 明细项容器 --> <div id="sodtl-container"> <!-- 默认一行 --> <div class="sodtl-row"> <input name="SODTL[].Dtl" type="text" placeholder="明细内容"> <input name="SODTL[].Code" type="text" placeholder="编码"> <button type="button" onclick="removeRow(this)">删除</button> </div> </div> <!-- 新增按钮 --> <button type="button" onclick="addSodtlRow()">新增明细</button> <button type="submit">提交</button> </form> <script> // 新增明细行 function addSodtlRow() { const container = document.getElementById("sodtl-container"); const row = document.createElement("div"); row.className = "sodtl-row"; row.innerHTML = ` <input name="SODTL[].Dtl" type="text" placeholder="明细内容"> <input name="SODTL[].Code" type="text" placeholder="编码"> <button type="button" onclick="removeRow(this)">删除</button> `; container.appendChild(row); } // 删除明细行 function removeRow(btn) { btn.parentElement.remove(); } </script>
第二步:收集数据并发送请求
const form = document.getElementById("your-form-id"); form.addEventListener("submit", function(e) { e.preventDefault(); // 阻止默认表单提交 // 构造请求对象 const postObj = { Key: this.elements["Key"].value.trim(), Remark: this.elements["Remark"].value.trim(), SODTL: [] }; // 遍历所有明细行收集数据 const sodtlRows = document.querySelectorAll(".sodtl-row"); sodtlRows.forEach(row => { const dtlInput = row.querySelector('input[name="SODTL[].Dtl"]'); const codeInput = row.querySelector('input[name="SODTL[].Code"]'); const dtlVal = dtlInput.value.trim(); const codeVal = codeInput.value.trim(); if (dtlVal || codeVal) { postObj.SODTL.push({ Dtl: dtlVal, Code: codeVal }); } }); // 发送XHR请求 const xhr = new XMLHttpRequest(); xhr.open("POST", "你的API地址", true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { console.log("请求成功", xhr.responseText); } else { console.error("请求失败", xhr.statusText); } }; xhr.send(JSON.stringify(postObj)); });
补充:用FormData简化动态数据收集
如果后端支持解析application/x-www-form-urlencoded格式的嵌套数组,也可以用FormData批量收集数据,再转换为目标JSON结构:
form.addEventListener("submit", function(e) { e.preventDefault(); const formData = new FormData(this); const postObj = { Key: formData.get("Key").trim(), Remark: formData.get("Remark").trim(), SODTL: [] }; // 批量获取所有明细字段的值 const dtlList = formData.getAll("SODTL[][Dtl]"); const codeList = formData.getAll("SODTL[][Code]"); for (let i = 0; i < dtlList.length; i++) { const dtlVal = dtlList[i].trim(); const codeVal = codeList[i].trim(); if (dtlVal || codeVal) { postObj.SODTL.push({ Dtl: dtlVal, Code: codeVal }); } } // 发送请求逻辑同上... });
这种方式需要把输入框的name改成SODTL[][Dtl]和SODTL[][Code]。
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

