エッジケースがない限り、フォームの作成は簡単です。 その後、ベーコンの脂肪が排水管に流れ込み、パイプが台無しになります。 そのため、ツールベルトに追加のツールが必要になる場合があります。 The FormData API あなたのツールの1つになることができます。

コアFormDataAPI

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>

もう1つの重要な落とし穴は、 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
//}

キー値を上書きしたい場合は、他の機能を使用する必要があります。

高度なフォーム

The 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で起動できます。できる限り回答します!