type="file" 型の <input> 要素は、ユーザーが一つまたは複数のファイルを機器のストレージから選択することができるようにします。選択されると、ファイルはフォーム投稿を使用してサーバーにアップロードしたり、 JavaScript コードと File API を使用して操作したりすることができます。

<input name="myFile" type="file">

選択されたファイルのパスを表す DOMString です。
イベント change 及び input
対応する共通属性 accept, multiple, required
IDL 属性 files 及び value
メソッド select()

ファイル入力欄の value 属性には、選択されたファイルへのパスを表す DOMString が入ります。ユーザーが複数のファイルを選択すると、 value は選択されたファイルのリストのうち最初のファイルを表します。その他のファイルは input 要素の HTMLInputElement.files プロパティを使って得ることができます。

メモ:
  1. 複数のファイルが選択された場合、文字列は最初に選択されたファイルを表します。 JavaScript は他のファイルに input の FileList プロパティを通してアクセスすることができます。
  2. ファイルが選択されていない場合、文字列は "" (空) になります。
  3. 疑わしいソフトウェアがユーザーのファイル構造を推測することを防止するため、文字列には C:\fakepath\ の接頭辞が付きます

追加の属性

すべての <input> で共通の属性に加え、 file 型の入力欄は次のものに対応しています。

files
選択されたそれぞれのファイルのリストである FileList オブジェクトです。このリストは multiple 属性が指定されていないと、1つしかメンバーがありません。

ファイル入力欄の使用

基本的な例

<form method="post" enctype="multipart/form-data">
 <div>
   <label for="file">アップロードするファイルを選択してください</label>
   <input type="file" id="file" name="file" multiple>
 </div>
 <div>
   <button>送信</button>
 </div>
</form>

これは以下のような出力になります。

メモ: この例は GitHub にもあります。 — ソースコードライブ実行を確認してください。

ユーザーの機器やオペレーティングシステムに関わらず、ファイル入力欄にはユーザーがファイルを選択することができるファイル選択ダイアログを開くボタンがあります。

上記のように、 multiple 属性を含めると、複数のファイルを一度に選択することができることを指定します。ユーザーはファイル選択ダイアログから、プラットフォームが許す方法 (例えば、 Shift 又は Control を押しながらクリック) によって、複数のファイルを選択できます。ユーザーに <input> あたり1つのファイルを選択させたい場合は、 multiple 属性を省略してください。

フォームが送信されると、それぞれの選択されたファイルの名前が URL 引数に ?file=file1.txt&file=file2.txt の様式で

追加されます。

選択されたファイルの情報の取得

選択されたファイルは、要素の files プロパティで返され、これは File オブジェクトのリストを含む FileList オブジェクトです。 FileList は配列のようにふるまうので、 length プロパティを使用して選択されたファイルの数を取得することができます。

それぞれの File オブえジェクトは以下のような情報を持っています。

name
ファイルの名前です。
lastModified
ファイルが最後に変更された日時を表す数値で、 UNIX 時刻 (1970年1月1日午前0時) からの経過ミリ秒数です。
lastModifiedDate
ファイルが最後に変更された日時を表す Date オブジェクトです。これは非推奨であり使うべきではありません。代わりに lastModified を使用してください。
size
バイト数によるファイルの長さです。
type
ファイルの MIME タイプです。
webkitRelativePath
ディレクトリ選択ダイアログ (つまり、 webkitdirectory 属性が設定されている file ダイアログ) で選択されたベースディレクトリからのファイルの相対パスを表す文字列です。これは標準外なので使用するには注意してください。

メモ: 最近のブラウザーはすべて、 HTMLInputElement.files の値を取得だけではなく設定もできるようになっています。これが最も後に追加されたのは Firefox で、バージョン57で追加されました (see バグ 1384030)。

受け付けるファイル型の制限

ふつう、ユーザーが自由な形式のファイルを選択できるようにはしたくないでしょう。代わりに、特定の形式のファイルを選択させたいでしょう。例えば、ファイル入力欄でユーザーにプロフィールファイルをアップロードさせるのであれば、おそらく JPEG 又は PNG のようなウェブに互換性がある画像形式を選択させたいでしょう。

受付可能なファイル形式は accept 属性で、受け付けるファイルの拡張子又は MIME タイプいくつか例を示します。

  • accept="image/png" 又は accept=".png" — PNG ファイルを受け付けます。
  • accept="image/png, image/jpeg" 又は accept=".png, .jpg, .jpeg" — PNG 又は JPEG ファイルを受け付けます。
  • accept="image/*"image/* の MIME タイプである任意のファイルを受け付けます。 (多くのモバイル機器では、この場合にユーザーがカメラで写真を撮ることもできるようになっています。)
  • accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" — MS Word 文書と思われるファイルをすべて受け付けます。

もっと複雑な例を見てみましょう。

<form method="post" enctype="multipart/form-data">
  <div>
    <label for="profile_pic">アップロードするファイルを選択してください</label>
    <input type="file" id="profile_pic" name="profile_pic"
          accept=".jpg, .jpeg, .png">
  </div>
  <div>
    <button>送信</button>
  </div>
</form>

これは前回の例と似た外見の出力をします。

メモ: この例は GitHub にもあります。 — ソースコードライブ実行を確認してください。

同じように見えるかもしれませんが、この入力欄でファイルを選択しようとすると、このファイル選択ダイアログでは accept の値で指定されたファイル形式しか選択できません。 (細かい動きはブラウザーやオペレーティングシステムによって異なります)。

macOS のファイル選択ダイアログのスクリーンショットです。 JPEG 以外のファイルは灰色になり選択できません。

accept 属性は選択されたファイルの形式を検証しません。単にブラウザーにユーザーが正しいファイル形式を選択するためのガイドするためのヒントを出すだけです。 (多くの場合) ユーザーがファイル選択ダイアログオプションを切り替えることで、ファイル選択ダイアログがこの設定を上書きして任意のファイルを選択することができるので、不正なファイル形式を選択する可能性があります。

このため、 accept 属性は適切なサーバー側の検証でバックアップする必要があることを意識しておいてください。

この例では、この例では、 HTMLInputElement.files プロパティで利用できるファイル情報を利用する、さらに高度なファイル選択ダイアログを示し、またいくつか巧妙なテクニックを示します。

メモ: この例の完全なソースコードは GitHub — file-example.html (ライブ版もあります) で見ることができます。 CSS については説明しません。 JavaScript が中心です。

最初に、 HTML を見てみましょう。

<form method="post" enctype="multipart/form-data">
  <div>
    <label for="image_uploads">アップロードする画像を選択してください (PNG, JPG)</label>
    <input type="file" id="image_uploads" name="image_uploads" accept=".jpg, .jpeg, .png" multiple>
  </div>
  <div class="preview">
    <p>アップロードするファイルが選択されていません</p>
  </div>
  <div>
    <button>送信</button>
  </div>
</form>

これは以前見たものに似ています。特筆するべきものはありません。

次に、 JavaScript を一通り見てみましょう。

スクリプトの最初の行で、フォームの入力欄自体と .preview クラスが設定された <div> 要素の参照を取得します。次に <input> 要素を非表示にします。 — これは、ファイル入力欄が概して醜く、スタイル付けをするのが難しく、ブラウザー間でデザインに一貫性がないからです。 <label> をクリックすることで input 要素をアクティブ化することができるので、 input 要素を見かけは非表示にしてラベルをボタンらしくしたほうが、ユーザーがファイルをアップロードしたいときの操作が分かります。

var input = document.querySelector('input');
var preview = document.querySelector('.preview');

input.style.opacity = 0;

メモ: ファイル入力欄を非表示にするのに visibility: hiddendisplay: none ではなく opacity を使用しているのは、支援技術が前ニ者のファイル入力欄が対話可能ではないと解釈するからです。

次に、イベントリスナーを入力欄に追加して、選択された値の変化 (この場合、ファイルが選択されたこと) を監視します。イベントリスナーは独自の updateImageDisplay() 関数を呼び出します。

input.addEventListener('change', updateImageDisplay);

updateImageDisplay() 関数が呼び出されるたびに、以下のことを行います。

  • while ループを使ってプレビューの <div> の中にある以前のコンテンツを空にします。
  • 選択されたすべてのファイルの情報を持つ FileList オブジェクトを取り、 curFiles と呼ばれる変数に保存します。
  • curFiles.length が0かどうかをチェックすることで、ファイルが選択されていないかを確認します。選択されていない場合は、プレビューの <div> に選択されているファイルがない旨のメッセージを表示します。
  • ファイルが選択されていた場合、ループで1つずつ、プレビューの <div> にそれについての情報を表示します。特筆するべきは次です。
  • 独自の validFileType() 関数を使用して、ファイルが正しい形式 (つまり、 accept 属性で指定された画像形式) であるかどうかをチェックします。
  • そうであるなら、次のことを行います。
    • ファイルの名前とファイルの長さを、前述の <div> (curFiles[i].name 及び curFiles[i].size で取得) 内のリストアイテムに出力します。独自の returnFileSize() 関数はファイルの長さを バイト/KB/MB のうち適切な形式で返します (既定でブラウザーは長さを絶対的なバイトで返します)。
    • window.URL.createObjectURL(curFiles[i]) を呼び出して、画像のプレビューのサムネイルを生成し、 CSS の画像の寸法を縮小し、それから画像もリストのアイテムに追加します。
  • ファイル形式が無効である場合、リストのアイテム内にメッセージを表示して、ユーザーに別なファイル形式を選択する必要があることを伝えます。
function updateImageDisplay() {
  while(preview.firstChild) {
    preview.removeChild(preview.firstChild);
  }

  var curFiles = input.files;
  if(curFiles.length === 0) {
    var para = document.createElement('p');
    para.textContent = 'アップロードするファイルが選択されていません';
    preview.appendChild(para);
  } else {
    var list = document.createElement('ol');
    preview.appendChild(list);
    for(var i = 0; i < curFiles.length; i++) {
      var listItem = document.createElement('li');
      var para = document.createElement('p');
      if(validFileType(curFiles[i])) {
        para.textContent = 'ファイル名 ' + curFiles[i].name + '、ファイルの長さ ' + returnFileSize(curFiles[i].size) + '。';
        var image = document.createElement('img');
        image.src = window.URL.createObjectURL(curFiles[i]);

        listItem.appendChild(image);
        listItem.appendChild(para);

      } else {
        para.textContent = 'ファイル名 ' + curFiles[i].name + ' はファイル形式が有効ではありません。選択し直してください。';
        listItem.appendChild(para);
      }

      list.appendChild(listItem);
    }
  }
}

独自の validFileType() 関数は File オブジェクトを引数として取り、それから受け付けるファイル形式のリストをループして、ファイルの type プロパティと一致するかどうかをチェックします。一致するものが見つかれば、関数は true を返します。一致するものが見つからなければ、 false を返します。

var fileTypes = [
  'image/jpeg',
  'image/pjpeg',
  'image/png'
]

function validFileType(file) {
  for(var i = 0; i < fileTypes.length; i++) {
    if(file.type === fileTypes[i]) {
      return true;
    }
  }

  return false;
}

returnFileSize() 関数は数値 (現在のファイルの size プロパティから取得したバイト数) を取り、バイト/KB/MB のうち適切な形式で返します。

function returnFileSize(number) {
  if(number < 1024) {
    return number + 'bytes';
  } else if(number > 1024 && number < 1048576) {
    return (number/1024).toFixed(1) + 'KB';
  } else if(number > 1048576) {
    return (number/1048576).toFixed(1) + 'MB';
  }
}

この例は次のようにできます。使ってみましょう。

仕様書

仕様書 策定状況 コメント
HTML Living Standard
<input type="file"> の定義
現行の標準 初回定義
HTML 5.1
<input type="file"> の定義
勧告 初回定義

ブラウザーの対応

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

機能 Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
基本対応 1.0 ? 1.0 (1.7 or earlier) (有) 1.0 1.0
機能 Android Chrome for Android Edge Firefox Mobile (Gecko) IE Mobile Opera Mobile iOS WebKit
(Safari/Chrome/Firefox/etc)
基本対応 (有) (有) (有) 4.0 (4.0) (有) (有) (有)

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: mfuji09
 最終更新者: mfuji09,