質問やフィードバックがありましたら、フォームからお願いします
本文は台湾華語で、ChatGPT で翻訳している記事なので、不確かな部分や間違いがあるかもしれません。ご了承ください
前回の記事では、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でデータを動的に更新する方法が発展しました。
動的更新の方法は確かにユーザー体験を改善しましたが、良いフォームデザインを実現するには多くの詳細に配慮する必要があります:
- エラーハンドリング
- 状態遷移
- データ保存
- アクセシビリティ
多くの場合、一つの環境がうまくいかないと、ユーザーはむしろシンプルな全ページ更新のフォームタグを使いたがります。特にバックエンドアプリケーションの場合、<form>
タグを使用して全ページ更新を行うことで、開発時間を大幅に節約でき、ブラウザの内蔵メカニズムを利用することで、より安定して動作することが多いです。
FormDataのJavaScriptにおける応用
FormDataは、開発者がkey/valueのアプリケーションを簡単に扱えるインターフェースを定義しており、最も一般的なのはフォーム処理です。FormData
の宣言は以下のように書けます:
const formData = new FormData()
// key value
formData.append('name', 'Kalan');
formの要素を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>
さらに、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コードを実行し、Networkのリクエストを観察すると、特にContent-Typeを定義していなくても、ブラウザが自動的にmultipart/form-data
形式で送信し、form dataのシリアライズもブラウザによって行われることがわかります。
まとめ
この二つの記事では、multipart/form-data
の応用と実際の使用方法について説明しました。第一の記事では、Content-Disposition
の意味、boundaryの用途、そしてmultipart/form-dataのリクエストがどのように構築されるかについて説明しました。第二の記事では、実務においてフォームとFormDataをどのように使用し、JavaScriptを介してFormDataの処理とファイルアップロードを行うかについて説明しました。
サーバーサイドにとって、ウェブ上でファイルアップロードを行うことも一つのHTTPリクエストであるため、サーバーはヘッダー内の情報とmultipart/form-data
で定義された形式に基づいてデータを解析する必要があります。そうしないと、正しくファイルの内容を取得することができません。通常、これらの解析はフレームワークによって処理されていますが、ここで特に強調したいのは、ウェブ上でファイルをアップロードすることには特別な魔法はなく、その背後にはHTTPリクエストが基盤となっているということです。
この記事が役に立ったと思ったら、下のリンクからコーヒーを奢ってくれると嬉しいです ☕ 私の普通の一日が輝かしいものになります ✨
☕Buy me a coffee