在靠近用户的地方部署容器
本工程教育(EngEd)计划由科支持。
在全球范围内即时部署容器。Section是经济实惠、简单而强大的。
免费开始使用。
如何将表单数据格式化为JSON
2022年2月17日
浏览器Fetch API用于从前端的网页向后端的API端点发出请求。
另一方面,浏览器FormData API提供了一种访问HTML表单字段的精确方法。这两个本地支持的浏览器API使得发送请求变得很容易。然而,要将数据作为JSON发送到API端点,这需要额外的工作。在本教程中,我们将逐步探讨如何捕获表单字段数据,将其格式化为JSON数据并发送至API端点。
目录
- 前提条件
- HTML表单模板
- 监听表单提交
- 用FormData API读取表单字段的值
- 将数据转换成JSON格式并发出POST请求
- 完整的代码
- 在Nodejs和Express.js API中处理JSON请求体
- 总结
前提条件
要继续学习本教程,需要具备以下基本知识。
在本教程结束时,你应该有一个可以工作的HTML表单,将表单数据作为JSON发送到一个API端点。在这个过程中,你将学习如何利用本地浏览器的Fetch和FormData API来实现这一目标。最后,你将拥有一个简单的Express Node.js API,它将监听你发送的请求并发回响应。
HTML表单模板
<form id="sample-form" method="post" action="http://localhost:5500/form">
<h1>Sample Form</h1>
<section>
<fieldset>
<h3>Gender</h3>
<ul>
<li>
<label for="gender_1">
<input type="radio" id="gender_1" name="gender" value="Male" />
Male
</label>
</li>
<li>
<label for="gender_2">
<input type="radio" id="gender_2" name="gender" value="Female" />
Female
</label>
</li>
</ul>
</fieldset>
<p>
<label for="user-fullname">
<span>Full Name: </span>
<strong><abbr title="required">*</abbr></strong>
</label>
<input type="text" id="user-fullname" name="username" />
</p>
<p>
<label for="user-mail">
<span>E-mail: </span>
<strong><abbr title="required">*</abbr></strong>
</label>
<input type="email" id="user-mail" name="usermail" />
</p>
<p><button type="submit">Submit Form</button></p>
</section>
</form>

在这里,我们有一个带有2个单选按钮的表单,用于选择男性或女性的性别,还有2个输入字段,用于输入全名和电子邮件地址,以及一个用于提交表单的按钮。
倾听表单提交的声音
通过ID获取表单。
//Get the form element by id
let sampleForm = document.getElementById("sample-form");
当表单的提交按钮被点击时,浏览器会发出一个事件,这个事件被表单的提交事件监听器捕获。定义表单提交时的事件处理程序,阻止浏览器的默认行为,这样你就可以处理它。
//Define the event handler for the form when it's submitted
sampleForm.addEventListener("submit", async (e) => {
//Prevent browser default behavior
e.preventDefault();
// More code here in the next step
}
用FormData API读取表单字段的值
FormData API提供了一种精确的方法来访问HTML表单字段的值,它通过获取附加到事件处理程序的元素来传递给它对表单元素的引用。然后从表单的action 属性中获取URL。
这就获得了所有的表单字段,并通过FormData实例使表单字段的值成为键值对。然后调用postFormFieldsAsJson() 函数(在下一步中定义它),并将url 和formData 实例作为参数传递。
//Define the event handler for the form when it's submitted
sampleForm.addEventListener("submit", async (e) => {
//Prevent browser default behavior
e.preventDefault();
//Get the entire form fields
let form = e.currentTarget;
//Get URL for api endpoint
let url = form.action;
try {
//Form field instance
let formFields = new FormData(form);
//Call the `postFormFieldsJson()` function
let responseData = await postFormFieldsAsJson({ url, formFields });
} catch (error) {
// Handle the error here.
console.error(`An has occured ${error}`);
}
}
将数据形成JSON格式并发出POST请求
默认情况下,将FormData 实例直接传递给fetch ,请求主体被格式化为 "multipart",请求头中的Content-Type 被设置为multipart/form-data 。将FormData实例转换为一个普通对象,然后再转换为JSON字符串。
使用Object.fromEntries()方法从formData instance创建一个对象。
使用JSON.stringify()方法,然后将普通表单数据格式化为JSON。
指定HTTP请求方法为POST,并使用Fetch API的头域指定你正在发送一个JSON主体请求并接受JSON响应。
然后将请求主体设置为从表单字段创建的JSON。现在发送请求并监听响应。如果响应是OK ,返回响应体,否则抛出一个错误。
/**
* Helper function to POST data as JSON with Fetch.
*/
async function postFormFieldsAsJson({ url, formData }) {
//Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries());
// Format the plain form data as JSON
let formDataJsonString = JSON.stringify(formDataObject);
//Set the fetch options (headers, body)
let fetchOptions = {
//HTTP method set to POST.
method: "POST",
//Set the headers that specify you're sending a JSON body request and accepting JSON response
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
// POST request body as JSON string.
body: formDataJsonString,
};
//Get the response body as JSON.
//If the response was not OK, throw an error.
let res = await fetch(url, fetchOptions);
//If the response is not ok throw an error (for debugging)
if (!res.ok) {
let error = await res.text();
throw new Error(error);
}
//If the response was OK, return the response body.
return res.json();
}
完整的代码
这是完整的JavaScript代码,带有上面步骤的内联注释。使用浏览器的FormData API捕获表单字段,将其转换为JSON,最后使用浏览器的Fetch API将其发送到API端点。
//Get the form element by id
const sampleForm = document.getElementById("sample-form");
//Add an event listener to the form element and handler for the submit an event.
sampleForm.addEventListener("submit", async (e) => {
/**
* Prevent the default browser behaviour of submitting
* the form so that you can handle this instead.
*/
e.preventDefault();
/**
* Get the element attached to the event handler.
*/
let form = e.currentTarget;
/**
* Take the URL from the form's `action` attribute.
*/
let url = form.action;
try {
/**
* Takes all the form fields and make the field values
* available through a `FormData` instance.
*/
let formData = new FormData(form);
/**
* The `postFormFieldsAsJson()` function in the next step.
*/
let responseData = await postFormFieldsAsJson({ url, formData });
//Destructure the response data
let { serverDataResponse } = responseData;
//Display the response data in the console (for debugging)
console.log(serverDataResponse);
} catch (error) {
//If an error occurs display it in the console (for debugging)
console.error(error);
}
});
/**
* Helper function to POST data as JSON with Fetch.
*/
async function postFormFieldsAsJson({ url, formData }) {
//Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries());
// Format the plain form data as JSON
let formDataJsonString = JSON.stringify(formDataObject);
//Set the fetch options (headers, body)
let fetchOptions = {
//HTTP method set to POST.
method: "POST",
//Set the headers that specify you're sending a JSON body request and accepting JSON response
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
// POST request body as JSON string.
body: formDataJsonString,
};
//Get the response body as JSON.
//If the response was not OK, throw an error.
let res = await fetch(url, fetchOptions);
//If the response is not ok throw an error (for debugging)
if (!res.ok) {
let error = await res.text();
throw new Error(error);
}
//If the response was OK, return the response body.
return res.json();
}
以JSON形式发送的样本表单数据(formDataToJsonString)对象。
{
"title": "Male",
"username": "gisioraelvis",
"usermail": "gisioraelvis@gmail.com"
}
在Node.js和Express.js API中处理JSON请求体
使用Node.js和Express.js实现一个简单的API,将暴露一个端点,你将把包含表单数据的请求作为JSON发送。
设置API
Node.js应该已经安装在你的电脑上。要检查它是否已经安装,请运行以下命令。
node -v
否则,请使用下面的说明安装它。
在项目根文件夹内,运行以下npm 命令来初始化Node.js项目。
npm init
填写相关字段,然后进入下一个步骤。
或者,你可以选择用NPM默认值自动初始化项目,在这种情况下,运行npm init -y 。查看这份深入的npm指南,了解如何使用NPM。
使用的npm包。
-
Express - 运行服务器,并暴露一个端点,你将
POST我们的请求。这里有一个链接可以了解更多关于Express.js的信息。 -
Nodemon- 这个开发包确保服务器在你进行修改时热重新加载,所以你不必在每次修改时重新启动服务器。
-
CORS或跨原点资源共享,允许你从不同的原点发送和接受请求,绕过应用于RESTful APIs的默认证券。一篇关于在Express.js中使用CORS的精彩文章。
安装必要的依赖项
这是安装列出的Node.js包的所有步骤。
npm install cors express
和
npm install --save-dev nodemon
Express API/服务器的代码。
let express = require("express");
let app = express();
var cors = require("cors");
//cors to allow cross origin resource sharing
app.use(cors());
//Middleware to parse the body of the request as JSON
app.use(express.json());
//The API endpoint that the form will POST to
app.post("/formdata-as-json", (request, response) => {
//Destructure the request body
let resData = {
serverData: request.body,
};
//Console log the response data (for debugging)
console.log(resData);
//Send the response as JSON with status code 200 (success)
response.status(200).json(resData);
});
//Start the server on port 5500
app.listen(5500, () => console.log(`we're live 🎉`));
在package.json文件中配置以下启动脚本。
"dev": "nodemon api"
为了启动服务器,运行
npm run dev
在终端上运行API的控制台响应。

浏览器上的控制台响应。

以下是GitHub上完整项目的链接。
总结
这就是你所拥有的!如何使用浏览器FormData API将表单数据格式化为JSON,并使用浏览器Fetch API将其POST到API端点,这是一个循序渐进的过程。你可以利用这些新获得的知识和技能来开发其他应用程序,利用这些强大的本地浏览器API。
编码愉快!
同行评审的贡献者。Jethro Magaji