1. ホーム
  2. HTML

【HTML】input type=”file” でファイルアップロードを作る方法|accept・multiple と値の取得を解説

Share

プロフィール画像のアップロードや、書類の添付に使う「ファイルを選択」ボタンは、<input type="file"> で作れます。受け付けるファイルの種類を絞る accept、複数選択を許す multiple、スマホでカメラを起動する capture など、属性を組み合わせて使い勝手を整えられます。この記事では、ファイル入力の基本から、選択されたファイルを JavaScript で読み取る方法、フォームで送信するときの注意点、そしてつまずきやすいポイントまで、初心者の方にも分かるように解説します。

ファイル入力の基本

input 要素の typefile を指定すると、「ファイルを選択」ボタンが表示され、クリックすると OS のファイル選択ダイアログが開きます。何の入力かを示すために、label と結び付けておきます。

index.html
<label for="avatar">プロフィール画像</label>
<input type="file" id="avatar" name="avatar">

選択されたファイルは画面に表示されるわけではなく、ファイル名がボタンの横に出るだけです。実際にプレビューを出したり中身を扱ったりするには、後述する JavaScript やサーバー側の処理が必要になります。

accept で受け付ける種類を絞る

accept 属性を付けると、選択ダイアログで表示されるファイルの種類を絞り込めます。画像だけ、PDF だけ、といった指定ができ、利用者が誤ったファイルを選びにくくなります。指定方法は、拡張子(.png)・MIMEタイプ(image/png)・ワイルドカード(image/*)です。

index.html
<!-- 画像ファイル全般だけを受け付ける -->
<input type="file" name="photo" accept="image/*">

<!-- 拡張子で複数指定(カンマ区切り) -->
<input type="file" name="doc" accept=".pdf,.docx">

注意したいのは、accept はあくまで選択ダイアログの絞り込みの目安であり、強制ではない点です。利用者がダイアログ側の設定を変えれば、別の種類のファイルも選べてしまいます。種類の検証は、後述の JavaScript やサーバー側でも必ず行ってください。

multiple で複数のファイルを選ぶ

multiple 属性を付けると、一度に複数のファイルを選択できるようになります。値を持たない属性で、書くだけで有効になります。アルバムへの一括アップロードなどに便利です。

index.html
<!-- 複数の画像をまとめて選べる -->
<input type="file" name="photos" accept="image/*" multiple>

スマートフォンでは、capture 属性を付けると、ファイル選択の代わりにカメラやマイクを直接起動できます(capture="user" でフロントカメラ、capture="environment" で背面カメラ)。対応は端末やブラウザによりますが、その場で撮影してアップロードさせたいときに使えます。

選択されたファイルを JavaScript で読み取る

選択されたファイルの情報は、input 要素の files プロパティに FileList として入っています。各ファイルは File オブジェクトで、名前(name)・サイズ(size)・種類(type)を読み取れます。ファイルが選ばれた瞬間を捉えるには change イベントを使います。

main.js
const input = document.getElementById("avatar");

input.addEventListener("change", () => {
  const file = input.files[0]; // 最初のファイル
  if (!file) return;           // 未選択なら何もしない

  console.log(file.name); // 例: photo.png
  console.log(file.type); // 例: image/png
  console.log(file.size); // バイト数(数値)
});

multiple で複数選択した場合は、input.files をループで回せば1つずつ扱えます。size はバイト単位の数値なので、file.size > 5 * 1024 * 1024 のように比較すれば「5MBより大きいファイルを弾く」といったチェックができます。

画像のプレビューを表示する

選んだ画像をその場で表示するには、URL.createObjectURL() でファイルから一時的な URL を作り、imgsrc に設定します。サーバーへ送る前に確認させたいときに便利です。

main.js
const input = document.getElementById("avatar");
const preview = document.getElementById("preview");

input.addEventListener("change", () => {
  const file = input.files[0];
  if (!file) return;
  // ファイルから一時URLを作って画像に表示する
  preview.src = URL.createObjectURL(file);
});

フォームで送信するときの設定

ファイルをサーバーへ送る場合、form 側の設定が重要です。method="post" にしたうえで、enctype="multipart/form-data" を必ず指定します。この enctype が無いと、ファイルの中身は送信されず、ファイル名だけが送られてしまいます。

index.html
<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="avatar" accept="image/*">
  <button type="submit">アップロード</button>
</form>

サーバー側(PHP なら $_FILES)でファイルを受け取り、保存します。受け取ったあとは、種類・サイズ・拡張子の検証を行うことが大切です。クライアント側の accept やチェックはあくまで補助で、最終的な安全性はサーバー側の検証で担保します。

うまくいかないときの確認ポイント

ファイルが送信されないとき

もっとも多いのが、formenctype="multipart/form-data" を付け忘れているケースです。また送信方式が get になっているとファイルは送れません。method="post"enctype の両方を確認してください。inputname が無い場合も、サーバー側で受け取れません。

値を JavaScript で設定できないとき

セキュリティ上の理由から、input.value = "..." のように JavaScript からファイルの値を勝手に設定することはできません。利用者の操作なしに任意のファイルを選ばせるのを防ぐためです。選択を取り消したいときは input.value = "" で空にすることのみ可能です。

同じファイルを選ぶと change が起きないとき

一度選んだのと同じファイルをもう一度選んでも、値が変わらないため change イベントが発火しないことがあります。再選択を確実に拾いたいときは、処理の最後に input.value = "" で値をリセットしておくと、同じファイルでも毎回 change が起きるようになります。

まとめ

<input type="file"> は、ファイルのアップロード機能を作る基本の部品です。要点を整理します。

  • accept で種類を絞り、multiple で複数選択、capture でカメラ起動。
  • 選択されたファイルは input.filesFile オブジェクト)から名前・サイズ・種類を取得できる。
  • 画像プレビューは URL.createObjectURL() で作った URL を img に設定する。
  • 送信には method="post"enctype="multipart/form-data" が必須。
  • accept やクライアント側チェックは補助。検証はサーバー側でも必ず行う。

まずは accept="image/*" を付けたファイル入力を置き、change イベントでファイル名を表示するところから始めると、扱い方がつかめます。

参考ページ