使用 JavaScript FormData API 创建自定义表单

只要你没有边缘盒子,就很容易构建一个表格,然后面包脂肪会掉下来,你的管道会被破坏,所以有时你需要你的工具带中一些额外的工具来处理它,FormData API可能是你的工具之一。

核心 FormData API

FormData有很多功能,但唯一在所有浏览器中工作的方法是附件。 假设我们想为人们创建一个社交应用程序,以便他们分享他们的面包图像。

1<input type="text" name="author"  id="author-input" />
2<input type="text" name="title" id="title-input" />
3<input type="file" name="picture" id="picture-input" />
4<button id="submit-button">SUBMIT</button>

为了处理我们的数据,我们可以创建以下代码:

 1[label Module: bacon-form.js]
 2const inputs = document.getElementsByTagName('input');
 3// This object will keep track of the changes of inputs
 4const applicationState = {
 5  title: "",
 6  author: "",
 7  picture: ""
 8}
 9
10document.getElementById('submit-button').onclick = async () => {
11  // We create a new form object
12  const form = new FormData();
13  // we append each element to the form
14  form.append('title', applicationState.title);
15  form.append('author', applicationState.author);
16  form.append('picture', applicationState.picture);
17
18  const res = await fetch('https://postman-echo.com/post', {
19    method: 'POST',
20    mode: 'no-cors',
21    body: form
22  });
23  // ... Do something with the response
24}
25
26// The rest of this code is functional
27// It is not directly related to FormData
28
29// This for loop reflects input changes to the application's state
30for (let i = 0; i < inputs.length; i++) {
31  const input = inputs[i]
32  const inputName = input.name
33
34  input.onchange = (e) => {
35    let value = e.target.value
36    // updating the application state according to the input the user interacted with
37    if (inputName === 'picture' && e.target.files[0]) {
38      setPicture(e.target.files[0]);
39    } else {
40      applicationState[inputName] = value;
41    }
42  };
43}
44// setPicture takes a file reads it as a base64URL and assigns that value to application.picture
45const setPicture = (file) => {
46  const fr = new FileReader();
47  // Reading the data and encoding it as base64 to send it to the server
48  fr.readAsDataURL(file);
49  // When the data is done loading we assign it to picture
50  fr.onloadend = (fileData) => {
51    applicationState.picture = fileData.target.result;
52  }
53}

如果这是我们的贡献:

Input sample with author name Jack Misteli Picture Name Alligator Bacon and a picture file

然后我们按下提交按钮,我们大约会得到以下请求标题:

 1{
 2  "Accept-Encoding": "gzip, deflate, br",
 3  "Connection": "keep-alive",
 4  "Content-Length": "4369",
 5  "Content-Type": "multipart/form-data",
 6  "Host": "postman-echo.com",
 7  "Origin": "null",
 8  "Sec-Fetch-Mode": "no-cors",
 9  "Sec-Fetch-Site": "cross-site"
10}

然后是以下的身体:

1{
2  "title": "Alligator Bacon",
3  "author": "Jack Misteli",
4  "picture": "data:text/javascript;base64,iVBORw0KGgoAA......."
5}

请注意,FormData构建程序可以将表单数据作为参数,这样您可以:

 1[label Module: regular-form.html]
 2<form id="user-form">
 3  <input type="text" name="username">
 4  <input type="password" name="password">
 5  <input type="file" name="picture" id="picture-input"/>
 6  <input type="submit">
 7</form>
 8<script>
 9  document.getElementById('user-form').onsubmit = async function (e) {
10    e.preventDefault();
11    // here `this` is the user-form HTML element
12    const form = new FormData(this);
13    ///... send form to server
14  }
15</script>

另一个重要的Gotcha,是附加不会重写一个密钥,如果它已经存在。

1[label Module: double-bacon-form.js]
2const form = new FormData();
3form.append('baconType', 'pork');
4form.append('baconType', 'vegan');
5// When you send your form it will look like this:
6// {
7//  baconType: pork
8//  baconType: vegan
9//}

如果您想要重写一个关键值,则必须使用其他函数。

先进形式

FormData构建器和附件方法在所有浏览器中都可用。

  • FormData.has(key): 检查表格中的密钥是否存在
  • FormData.set(key, value): 更改与密钥相关的值
  • FormData.delete(key): 删除与密钥相关的条目
  • FormData.get(key): 访问与密钥相关的第一个值
  • FormData.getAll(key): 创建与密钥相关的所有值的数组。

就是这样,如果你有任何问题,你可以在Twitter上发出链接到文章,我会尽我所能回答他们!

Published At
Categories with 技术
Tagged with
comments powered by Disqus