使用JavaScriptFormDataAPI创建自定义表单
来自菜鸟教程
只要您没有边缘案例,构建表单就很容易。 然后培根脂肪会排到下水道,你的管道就毁了。 所以你有时需要在你的工具带中使用一些额外的工具来处理它。 FormData API 可以是您的工具之一。
核心表单数据 API
FormData 有很多功能,但唯一适用于所有浏览器的方法是 append。 假设我们要创建一个社交应用程序,供人们分享他们的培根图片。 在这里,我们将创建一个表单,允许用户发送带有标题和作者姓名的图片。 我们的 HTML 标记将如下所示:
<input type="text" name="author" id="author-input" /> <input type="text" name="title" id="title-input" /> <input type="file" name="picture" id="picture-input" /> <button id="submit-button">SUBMIT</button>
为了处理我们的数据,我们可以创建以下代码:
模块:bacon-form.js
const inputs = document.getElementsByTagName('input');
// This object will keep track of the changes of inputs
const applicationState = {
title: "",
author: "",
picture: ""
}
document.getElementById('submit-button').onclick = async () => {
// We create a new form object
const form = new FormData();
// we append each element to the form
form.append('title', applicationState.title);
form.append('author', applicationState.author);
form.append('picture', applicationState.picture);
const res = await fetch('https://postman-echo.com/post', {
method: 'POST',
mode: 'no-cors',
body: form
});
// ... Do something with the response
}
// The rest of this code is functional
// It is not directly related to FormData
// This for loop reflects input changes to the application's state
for (let i = 0; i < inputs.length; i++) {
const input = inputs[i]
const inputName = input.name
input.onchange = (e) => {
let value = e.target.value
// updating the application state according to the input the user interacted with
if (inputName === 'picture' && e.target.files[0]) {
setPicture(e.target.files[0]);
} else {
applicationState[inputName] = value;
}
};
}
// setPicture takes a file reads it as a base64URL and assigns that value to application.picture
const setPicture = (file) => {
const fr = new FileReader();
// Reading the data and encoding it as base64 to send it to the server
fr.readAsDataURL(file);
// When the data is done loading we assign it to picture
fr.onloadend = (fileData) => {
applicationState.picture = fileData.target.result;
}
}
如果这是我们的输入:
然后我们按下提交按钮,我们将大致得到以下请求头:
{
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Content-Length": "4369",
"Content-Type": "multipart/form-data",
"Host": "postman-echo.com",
"Origin": "null",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "cross-site"
}
以及以下正文:
{
"title": "Alligator Bacon",
"author": "Jack Misteli",
"picture": "data:text/javascript;base64,iVBORw0KGgoAA......."
}
请注意 FormData 构造函数可以将表单数据作为参数。 所以你可以这样做:
模块:regular-form.html
<form id="user-form">
<input type="text" name="username">
<input type="password" name="password">
<input type="file" name="picture" id="picture-input"/>
<input type="submit">
</form>
<script>
document.getElementById('user-form').onsubmit = async function (e) {
e.preventDefault();
// here `this` is the user-form HTML element
const form = new FormData(this);
///... send form to server
}
</script>
另一个重要的问题是 append 不会覆盖已经存在的键。
模块:double-bacon-form.js
const form = new FormData();
form.append('baconType', 'pork');
form.append('baconType', 'vegan');
// When you send your form it will look like this:
// {
// baconType: pork
// baconType: vegan
//}
如果要覆盖键值,则必须使用其他功能。
高级表格
FormData 构造函数和 append 方法在所有浏览器中都可用。 大多数其他方法都是自我描述的:
FormData.has(key):检查表单中是否存在键。FormData.set(key, value):更改与键关联的值。FormData.delete(key):删除与键关联的条目。FormData.get(key):访问与键关联的第一个值。FormData.getAll(key):创建与键关联的所有值的数组。FormData.keys()、FormData.values()、FormData.entries():迭代器用于获取 FormData 的所有键、关联值或条目。
🥓 就是这样,如果您有任何问题,您可以在 Twitter 上通过文章链接向他们提问,我会尽力回答!