カランのブログ

ソフトウェアエンジニア / 台湾人 / 福岡生活

今のモード ライト

上記の記事では、multipart/form-dataのリクエストフォーマットとその解決策について説明しました。この記事では、実際の開発で遭遇する問題とその応用について解説します。

具体的には、次のフォームアプリケーションに関連するいくつかの部分を含みます:

  • <form/>タグの背後で行われる処理
  • JavaScriptでのFormDataの使用
  • FormDataとfetchの組み合わせ
  • JavaScriptによるファイルの操作方法

formタグについて再考する

実際には、HTMLのformタグには、開発者が見落とすことがあるブラウザによって実装された詳細がたくさんあります。以下の例を考えてみましょう:

<form method="POST" action="/upload" enctype="multipart/form-data">
  <input type="text" name="name" />
  <input type="file"  name="file" />
  <button>
    Submit
  </button>
</form>

JavaScriptコードがない状態で、Submitボタンをクリックすると、ブラウザが以下のことを自動的に行います:

  • input内のnameとfileフィールドをシリアライズする
  • Content-Type: multipart/form-dataのHTTPリクエストでPOSTメソッドを送信する
  • ファイルを読み取り、リクエストのコンテンツに追加する(ファイルが存在する場合)

シングルページアプリケーションやフロントエンドフレームワークがまだ一般的ではなかった時代には、データを入力してフォームを送信し、他のページにリダイレクトするという方法が一般的でした。しかし、入力するデータが増えたり、一部の領域のみを更新する必要がある場合(コメントなど)、ユーザーにとってはページ全体を更新する必要があるため、ユーザーエクスペリエンスは良くありませんでした。そのため、Ajaxを使用してAPIを呼び出し、JavaScriptを使用してデータを動的に更新する方法が徐々に生まれました。

Desktop - 1

動的な更新方法はユーザーエクスペリエンスを改善するものの、良いフォームデザインを実現するには多くの細部を考慮する必要があります:

  • エラーハンドリング
  • ステート遷移
  • データの保存
  • アクセシビリティ

たとえ一つの要素がうまく機能しない場合、ユーザーは単純なページ全体の更新を行うフォームタグを使用することを好むことがしばしばあります。バックエンドアプリケーションの場合、<form>タグを使用してページ全体の更新を行うことで、多くの開発時間を節約することができ、さらにブラウザの組み込みメカニズムに依存してより安定した動作を実現できます。

JavaScriptでのFormDataの使用

FormDataは、開発者がキー/値のようなアプリケーションを簡単に作成できるインターフェースを定義しています。最も一般的なのは、フォーム処理です。FormDataの宣言は次のように行います:

const formData = new FormData()
//                キー     値
formData.append('name', 'Kalan');

フォームの要素をFormDataに入れると、入力された情報が自動的にFormDataにシリアライズされます:

<form id="form" enctype="multipart/form-data" action="/upload" method="POST">
  <input type="text" name="name" />
  <input type="file" name="file" />
  <button>Submit</button>
</form>

<script>
  const formData = new FormData(document.getElementById('form'));
  formData.get('name'); // 現在のinputの値を取得
  formData.get('file'); // 現在のファイルを取得
</script>

JavaScriptでのFormDataの使用

さらに、FormDataをfetchのbodyに入れると、ブラウザが自動的にmultipart/form-data形式で送信します:

const formData = new FormData();
formData.append('name', 'Kalan');
formData.append('file', new File(['Hello World'], 'file.txt', { type: 'text/plain' }))

fetch('/upload', {
  method: 'POST',
  body: formData
})

上記のJavaScriptコードを実行し、ネットワークリクエストを観察すると、Content-Typeを特に指定していなくても、ブラウザが自動的にmultipart/form-dataで送信し、フォームデータのシリアライズもブラウザによって行われることがわかります。

fetchとFormDataを使用してmultipart form-dataリクエストを送信する

結論

これらの2つの記事では、multipart/form-dataの使用と実際の使用方法について説明しました。最初の記事では、Content-Dispositionの意味、boundaryの目的、およびmultipart/form-dataリクエストの構築方法について説明しました。2番目の記事では、実際のプラクティスでformとFormDataをどのように使用し、JavaScriptを使用してFormDataを処理しファイルをアップロードするかについて説明しました。

サーバーサイドでは、Webページ上でのファイルのアップロードもHTTPリクエストとして扱われるため、サーバーサイドはヘッダーの情報とmultipart/form-dataで定義された形式に基づいてデータを解析する必要があります。通常、これらの解析はフレームワークによって処理されていますが、ここで特に注意すべきは、「ファイルの送信はHTTPリクエストの上に基づいており、神秘的な魔法は存在しない」ということです。

作者

Kalan 頭像照片,在淡水拍攝,淺藍背景

愷開 | Kalan

Kalan です。台湾出身で、2019年に日本へ転職し、福岡に住んでいます。フロントエンド開発に精通しているだけでなく、IoT、アプリ開発、バックエンド、電子工作などの分野にも挑戦しています。 最近、エレキギターを始めました。ブログを通じて、より多くの人と交流できればと思っています。気軽に絡んでください