<input type="file"> ファイルのアップロード・ボタン
HTMLの<input type="file">はファイルのアップロードボタンを設置するために使います。
<>HTML <input type="file" name="example" accept="image/jpeg, image/png"> すべて表示Webアプリケーションで画像などのアップロードの仕組みを作るときには欠かせません。ぜひ基本的な使い方をマスターしましょう。
このページの目次- ブラウザごとの表示や挙動
- 📱モバイル端末でも使用可能
- input type="file"の使い方
- formで送信する例
- accept属性:アップロード可能なファイル形式を制限する
- multiple属性:複数ファイルを選択可能にする
- required属性:ファイルの選択を必須にする
- JavaScriptで選択されたファイルデータを取得する
- Fileオブジェクトの内容
- ファイルサイズを制限する
- 画像のプレビューを表示する
- FileReader
- JavaScriptで画像を送信する ==中級者向け==
- CSSでボタンのデザインをカスタマイズ
- サンプルコード
ブラウザごとの表示や挙動
<input type="file">はIE含めて主要ブラウザすべてで使用できます。[ファイルを選択]ボタンをクリックすると、ファイルの選択ウィンドウが開きます。
📱モバイル端末でも使用可能こちらはiOS Safariでの表示例です。[ファイルを選択]⇒[フォトライブラリ]とタップすれば、端末内の画像を選択できます。
Androidのブラウザでも同じように端末内の画像を選択できます。このように、モバイルのブラウザからでもファイルのアップロードが可能です。
input type="file"の使い方
formで送信する例まず、ごく簡単なサンプルHTMLを紹介します。JavaScriptは使わずに、<form>でサーバーへデータを送る例です。
<>HTML <form method="post" enctype="multipart/form-data"> <input type="file" name="avatar"> <button type="submit">送信する</button> </form> すべて表示👆name属性でフィールドの名前を指定します。この名前があることでサーバーへ送信したときに「どの情報が、どのフィールドに対応しているのか」分かります。 name="avatar"なので、サーバーではファイルの情報はavatarに紐付いていることが分かるわけですね。
🤔 method="post"やenctype="multipart/form-data"の意味は?ファイルをサーバーに送るときには、<form>タグにmethod="post"やenctype="multipart/form-data"という属性を指定する必要があります。
method="post"デフォルトではmethod="get"となっています。getだとフォームの内容はURLにくっつく形(https://example.com?フィールド名=値)で送られます。テキストデータならこれで良いのですが、ファイルの中身はURLに含めることができません。 そこでmethod="post"を使うと、送信内容が(URLに付くのではなく)本文として送られます。postならファイルでも送信できるのです。
enctype="multipart/form-data"詳しい解説はここでは省略しますが、<form>にenctype="multipart/form-data"を指定すると、フォームデータの中に、文字列だけでなく様々な形式のデータを含めることが可能になります。
この方法だと、送信ボタンをクリックした時にページが遷移します。ページを切り替えることなくその場でファイルをアップロードしたい場合は、JavaScriptを使ってファイルを操作しましょう(のちほど解説します)。
accept属性:アップロード可能なファイル形式を制限するaccept属性では、受け付けるファイルの拡張子や種類を指定できます。複数指定するときは半角カンマ(,)で区切って並べます。
<>HTML <input type="file" name="example" accept=".png, .jpg, .jpeg, .pdf, .doc"> すべて表示👆accept="◯◯"に指定されている.png、.jpg、.jpeg、.pdf、.docの拡張子のファイルを選択できるようになります。
こちらはMacのファイル選択ウィンドウです。accept="◯◯"に指定されていない拡張子のファイルは選択できません。
MIMEタイプでの指定してもOK「MIMEタイプ」とは、ブラウザとサーバー間のやり取りで使われるファイル種類を表す情報のことです。たとえばPNG画像をMIMEタイプで表すとimage/pngとなります。拡張子.jpgと.jpegはimage/jpegという1つのMIMEタイプでまとめられます。
つまり、次の2つは同じ意味になります。
accept=".png, .jpeg, .jpg" accept="image/png, image/jpeg" 画像ファイル全般を許可する場合 <input type="file" name="example" accept="image/*">👆「画像ファイルなら選択可」という場合にはimage/*と指定します。
multiple属性:複数ファイルを選択可能にするinputタグにmultiple属性を指定すると、複数のファイルの選択が可能になります。
<>HTML <input type="file" name="example" accept="image/*" multiple> すべて表示このように複数のファイルをまとめて選択できるようになります。
required属性:ファイルの選択を必須にする <>HTML <form> <input type="file" name="avatar" required> <button type="submit">送信する</button> </form> すべて表示このまま送信するとエラーに
👆<input>タグにrequiredを指定すると、ファイルの選択が必須になります。選択されていない場合は、送信時にブラウザによりエラーが表示されます。
ただし<form>タグ内に<input>と送信ボタンがある場合にのみ、エラーが表示されます。また、JavaScriptでファイルを送る場合は、このエラーは表示されないので注意しましょう。
JavaScriptで選択されたファイルデータを取得する
File APIというものを使えば、JavaScriptでより自由にファイルを操作できます。独自のバリデーションや、非同期アップロードなども実現できます。
まずは、1つ〜複数のファイルが選択されたときに、1つ1つのファイルデータ(Fileオブジェクト)を取得してみたいと思います。HTMLではmultipleで複数選択できるようにします。
HTML <input type="file" id="example" multiple> JavaScript const fileInput = document.getElementById('example'); const handleFileSelect = () => { const files = fileInput.files; for (let i = 0; i < files.length; i++) { console.log(files[i]); } } fileInput.addEventListener('change', handleFileSelect);👆input要素.addEventListener('change', 関数)により、フィールドの値が変更された時(≒ファイルが選択された時)に関数を実行できます。
ファイルデータ一覧はinput要素.filesにより取得できます。ループ処理によりその中身を1つ1つ取り出しています(今回は単にコンソールに出力するだけにしました)。
たとえばJPEG画像を2枚選択した場合、コンソールの出力結果(つまりfiles[i]の中身)はこのようになります。
Fileオブジェクトの内容- name:ファイル名
- size:ファイルのサイズ(Byte)
- type:ファイルのMIMEタイプ
- lastModifiedDate:ファイルの最終更新日
たとえば、ファイル名はfiles[i].nameで、ファイルサイズfiles[i].sizeで取得できます。
ファイルサイズを制限する
次に「ファイルサイズが一定サイズ以上の場合、エラーメッセージを出して終了する」ということをやってみましょう。ここでは制限サイズを1MBとします(Byteで表すと1024 * 1024 * 1)。
HTML <input type="file" id="example" multiple> JavaScript const sizeLimit = 1024 * 1024 * 1; const fileInput = document.getElementById('example'); const handleFileSelect = () => { const files = fileInput.files; for (let i = 0; i < files.length; i++) { if (files[i].size > sizeLimit) { alert('ファイルサイズは1MB以下にしてください'); fileInput.value = ''; return; } } } fileInput.addEventListener('change', handleFileSelect);👆大まかな流れは、さきほどのサンプルと同じです。1つ1つのファイルデータのサイズ(Byte数)はfiles[i].sizeで取得できます。これを上限サイズの値と比較しているわけですね。 エラー時にはfileInput.value = '';でフィールドをリセットしています。これをやらないと、後で同ファイルが選択されたときにボタンが反応しなくなってしまいます。
CodePenのサンプルも貼り付けておきます。
👆1MB以上のファイルをアップロードしようとすると「ファイルサイズは1MB以下にしてください」というエラーメッセージが表示されます。
😿少し詳しい人がやろうと思えば、制限サイズ以上のファイルをサーバーに送りつけることも可能です。サーバー側でもファイルサイズをチェックするのが良いでしょう。
画像のプレビューを表示する
<input type="file">で画像が選択されたときに「プレビューを表示したい」というのはよくあることだと思います。こちらはFileReaderを使えば実現できます。
FileReaderFileReaderは、ファイルを読む込むための仕組み(API)です。FileReaderのreadAsDataURL()というメソッドを使うと、ファイルデータをURLとして読み込んでくれます。
画像の情報を1つのURLにまとめるため、とっても長いURLになります。 詳しくはFileReader - MDNが参考になります。
複数枚の画像プレビューに対応したサンプルコード HTML <input type="file" id="example" multiple> <div id="preview"></div> JavaScript プレビュー関数 function previewFile(file) { const preview = document.getElementById('preview'); const reader = new FileReader(); reader.onload = function (e) { const imageUrl = e.target.result; const img = document.createElement("img"); img.src = imageUrl; preview.appendChild(img); } reader.readAsDataURL(file); }👆ファイルデータ(file)を渡すとプレビュー画像をid="preview"要素の中に追加する関数です。reader.onload = function (e) { ... }の部分でURLを受け取り、画像要素を作成し、HTMLに追加しています。
完全なサンプルコードCodePenのサンプルも用意しました。画像選択時にファイルデータを取得し、previewFile関数にわたすところまでやっています。実際に画像プレビューが表示されることを確認してみてください。
JavaScriptで画像を送信する 中級者向け
非同期で画像データをサーバーに送信するやり方はいくつかあります。ライブラリを使わずにやるなら、FormDataで作成したフォームデータを、Fetchで送信するのが簡潔でしょう。
JavaScript ファイルデータを送信 const file = document.getElementById("example").files[0]; const formData = new FormData(); formData.append("avatar", file); fetch(送信先のURL, { method: "POST", body: formData });👆大まかな流れです。実際のアプリケーション開発では「async/awaitで非同期処理にする」「try/catchでエラーハンドリングする」なども必要になるでしょう。
CSSでボタンのデザインをカスタマイズ
<input type="file">で表示されるアップロードボタンの見た目は、CSSでカスタマイズできます。
サンプルコード HTMLまずHTMLは次のようにします。
<label class="upload-label"> ファイルを選択 <input type="file"> </label>👆<label>タグで<input type="file">を囲むことにより、<label>をクリックすればファイルの選択ウィンドウが開くようになります。デフォルトの選択ボタン(<input>)をCSSで隠してしまっても、<label>が選択ボタンの役割をしてくれるわけですね。
CSS<label>のクラスupload-labelに対してCSSでスタイルをあてていきます。
<>HTML #CSS <label class="upload-label"> ファイルを選択 <input type="file"> </label> .upload-label { display: inline-block; cursor: pointer; margin: 1em 0; padding: .7em 1em; line-height: 1.4; background: #3e8bff; color: #FFF; font-size: 0.95em; border-radius: 2.5em; transition: 0.2s; } .upload-label:hover { box-shadow: 0 8px 10px -2px rgba(0, 0, 0, 0.2); } .upload-label input { display: none; } すべて表示クリックでファイル選択が開く
👆デフォルトの<input>の見た目を変えるのは難しいので非表示にしてしまいます。そのうえで<label>を装飾し、ボタンらしく見せています。
その他の種類の<input>の使い方はこちらのページで解説しています。
関連するページを読む inputタグ・コンプリートガイド - HTML