https://idea-hack.com/blog/80524/
Dropzone.jsを使ってファイルをアップロードする方法と13のサンプルコード

Dropzone.jsを使ってファイルをアップロードする方法と13のサンプルコード

開発者も手を付けたくない。デザイナーもうんざり。だけどユーザーに使われないフォームですが、Dropzone.jsを使うとリッチに簡単に導入することができますので、やり方とサンプルコードを紹介します。

フォームの実装はセキュリティのことも踏まえると、実装が大変な機能の1つです。そのため、フォーム関連のツールやライブラリは一見の価値があります。その中でも「Dropzone.js」は多機能でデザインも良く、かつファイルのバリデート機能もついているので選択肢の1つに加えてみてはいかがでしょうか?

この記事では、Dropzoneの実装方法をいくつかのサンプルコードを踏まえて紹介します。

DropzoneJSとは

Dropzone.jsはユーザーにドラッグ & ドロップでのファイルアップロードを可能にしてくれます。

Desktopユーザーはこの方法でファイルをアップロードするのに慣れていますので、大変便利です。

ちなみに、Drag & Dropのブラウザサポートも幅広くなっているので、古いブラウザを使っている人が多いサイトを運営している場合でも敷居が低いでしょう。

Drag & DropのUXも素敵です。例えば、画像ファイルの場合、アップロードが完了した時点でサムネイルファイルの表示を行ってくれます。

複数の画像ファイルを一度にアップロードさせたい時に、どのファイルの区別がつきやすくユーザーに優しいです。

特徴

要約すると、主な特徴は下記の通りです。

  • JavaScript単体で利用可能。jQueryで使うこともできる
  • Drag & Dropのサポート
  • サムネイル画像の生成と表示
  • 複数のファイルの更新を同時に行うことができる
  • プログレスバーの表示
  • デザインの拡張性のしやすさ
  • ファイルが33kbで軽量

ブラウザサポート

公式ドキュメントによると、サポートされているブラウザーは下記の通り。

ブラウザバージョン
Chrome7 +
Firefox4 +
IE10 +
Opera12 +
Safari6 +
補足

ちなみに、Dropdown.jsではプラグインがブラウザにサポートされない場合にフォールバック機能を適用するオプションもついています。(もちろん、フォールバックの内容自体はご自身での開発が必要ですが・・・)

DropzoneJSのインストール

ファイルのダウンロードと読み込み

NPMパッケージをインストールしたい人はGithubからGitコマンドで任意のフォルダ にダウンロードしてください。

もちろんZIPでも問題ないですし、後述しますがCDNも提供されていますので、CDN使う人は飛ばして構いません。

git
npm install enyo/dropzone

Gitコマンドに詳しくない人は下記記事も参考にどうぞ。

Tips

この記事では解説範囲外としますが、Dropzone.jsは第三者によるReact.JS版の開発も進められています。React.JS版を利用する方はこちらをダウンロードしてください。

React版 Dropzone.js

必要なファイルの読み込み

ダウンロードファイルの中には開発環境向けのファイルも入っているので必要なファイルだけ読み込みます。

  • basic.min.css
  • dropzine.min.css
  • dropzone.min.js

CDNを読み込みたい方は下記コードをコピーしてください。

HTML
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/basic.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.css"/>

Dropzone.JSの基本的な使い方

Dropzone.JSをフォームに適用する最もシンプルな方法は「form要素にCSSクラスdropzoneを適用する」ことです。

Output
HTML
<form id="upload-widget" method="post" action="/upload" class="dropzone"></form>

basic.cssを読み込んでいるため、Dropzone.jsが用意したデフォルトのスタイルが読み込まれています。

実際にこのページに画像ををアップロードしてみてください。(サーバーサイド実装はしていないので、サイトには保存されません。)

技術的に必要な動作はこの時点で十分ですが、ほとんどのケースではいくつかのカスタムオプションを加えたいはずです。

カスタムオプションのフォーマットは下記の通りです。

JavaScript
Dropzone.options.【WIDGET_ID】 = {
  //
};

【WIDGET_ID】の部分はHTMLに記載した任意のID属性の値をつけるのですが、1つ注意点がありまして、キャメルケースにして書かなければいけません。

下記のようにします。

Output
HTML
<form id="upload-widget2" method="post" action="/upload" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget2 = {
  //
};

このサンプルコードではHTMLに付けたID属性の値を「upload-widget2」にしたので、JSではキャメルケースにして「uploadWidget2」になります。

別の書き方として、インスタンス化するのもありです。

この場合キャメルケースは必要ありません。コードは下記の通りです。

Output
HTML
<form id="upload-widget3" method="post" action="/upload" class="dropzone"></form>
JavaScript
var uploader = new Dropzone(‘#upload-widget3’, options);

Dropzone.JSのオプション項目

全ては紹介しきれませんが、いくつか主要の物を紹介します。

オプション全一覧

URL

アップロードフォームがデータを送信するURLです。必須のパラメーターですが、もしHTML内にaction属性を適用している場合は必要ないです。

Output
HTML
<form id="upload-widget4" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget4 = {
url: '/upload',
};

Method

MethodオプションはHTTPメソッドをセットするためのプロパティです。

ほとんdの場合はデフォルトのPOSTで問題ないでしょうが、必要に応じてGETなどを指定することができます。

Output
HTML
<form id="upload-widget5" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget5 = {
 url: '/upload',
method: 'post',
};

maxFiles

ユーザーがアップロードできるファイルをの最大数を指定します。

制限をなくしたければnullを指定します。

1つしかアップロードさせない様にするために、使用する人は多いと思います。

Output
HTML
<form id="upload-widget6" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget5 = {
 url: '/upload',
method: 'post',
maxFiles: '1',
};

maxFileSize

アップロードされるファイルの最大のサイズを指定することができます。制限なしであれば「null」をしてします。

公式サイトではややわかりづらく書いてありますが、単位は「MB」です。

Output
HTML
<form id="upload-widget6" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget6 = {
url: '/upload',
method: 'post',
maxFiles: '1',
maxFilesize: '2', //MB
};

clickable

デフォルトでは、ドラッグ & ドロップの他に、アップロードエリアをクリックすることでファイルダイアログが開き、そこからファイルを選択することも可能です。

Output
HTML
<form id="upload-widget7" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget7 = {
url: '/upload',
method: 'post',
maxFiles: '1',
maxFilesize: '2', //MB
clickable: false,
};

これが必要ない人は、このプロパティをfalseに変更しましょう。

acceptFiles

acceptFilesプロパティを使用すれば、アップロードを許可するファイル形式を指定できます。これは大変便利です。

MINE-typesで指定してあげる必要があり、複数指定する場合はコンマで区切ってください。

このサンプルでは画像だけ許可するコードを紹介します。

Output
HTML
<form id="upload-widget8" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget8 = {
 url: '/upload',
method: 'post',
maxFiles: '1',
maxFilesize: '2', //MB
clickable: false,
acceptedFiles: 'image/*',
};

サムネイル関連のプロパティ

サムネイル画像のWidthとHeightを指定することができます。

いくつかまとめました。ただ、たくさんあるので公式サイトも参考にしてください。

構文 意味
createImageThumbnailsサムネイル画像を生成するかどうか
thumbnailMethodサムネイルを切り抜く(crop)かそうでないか(contain)
thumbnailWidthサムネイルのWidth(デフォルトは120px)
thumbnailHeightサムネイルの幅(デフォルトは120px)
Output
HTML
<form id="upload-widget9" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget9 = {
 url: '/upload',
method: 'post',
maxFiles: '1',
maxFilesize: '2', //MB
clickable: false,
acceptedFiles: 'image/*',
createImageThumbnails: true,
thumbnailMethod: 'crop',
thumbnailWidth: 300,
thumbnailHeight: 300,
};

ちなみに、thumbnailWidththumbnailHeightnullにするとリサイズされず、そのままの画像が表示されます。

独自の追加処理

アップロード前にバリデートをかけたい場合は独自のカスタムコードを追加することができます。

ただし、このプラグインに含まれているプロパティでできることをここで行うことは推奨されていません。

KAZUKI

こちらは実際に動くサンプルは用意してません。ロジックだけの解説です。

JavaScript
accept: function(file, done) {
  if ( !someCheck() ) {
    return done('This is invalid!');
  }
  return done();
}

下記のように条件に応じてdone()メソッドを使うことができます。

done('This is invalid!');の様に引数を記入した場合、処理が中断され、エラーメッセージが出力されます。

引数がなし(done(); )の状態で返すと処理はそのまま続きます。

アップロードメッセージの変更

これもよく使いますね。特に英語圏ではないユーザーは必ず使うのではないでしょうか。

こちらはアップロード前のメーセージ内容を変更するために使います。

Output
HTML
<form id="upload-widget10" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget10 = {
 url: '/upload',
method: 'post',
maxFiles: '1',
maxFilesize: '2', //MB
clickable: false,
acceptedFiles: 'image/*',
createImageThumbnails: true,
thumbnailMethod: 'crop',
thumbnailWidth: 300,
thumbnailHeight: 300,
dictDefaultMessage: 'アップロードしたいファイルをこちらにドラッグ & ドロップで追加してください',
};

CSRFトークンの追加

アップロードにおいてセキュリティ対策は非常に重要です。CSRF (Cross Site Request Forgery) の防止のためにheadersプロパティを使ってHTTPリクエストに追加のHeader情報を付与しましょう。

KAZUKI

こちらは実際に動くサンプルは用意してません。ロジックだけの解説です。

まずはHTMLのheadタグ内に下記HTMLを追加します。

HTML
<meta name="csrf-token" content="CL2tR2J4UHZXcR9BjRtSYOKzSmL8U1zTc7T8d6Jz">

そしてJavaScrptを下記の様に書きます。

JavaScript
Dropzone.options.uploadWidget11 = {
 url: '/upload',
method: 'post',
maxFiles: '1',
maxFilesize: '2', //MB
clickable: false,
acceptedFiles: 'image/*',
createImageThumbnails: true,
thumbnailMethod: 'crop',
thumbnailWidth: 300,
thumbnailHeight: 300,
headers: {
  'x-csrf-token': document.querySelectorAll('meta[name=csrf-token]')[0].getAttributeNode('content').value,
},
};

詳しくない人向けに、jQueryのコードも書いておきます。

JavaScript
Dropzone.options.uploadWidget12 = {
 url: '/upload',
method: 'post',
maxFiles: '1',
maxFilesize: '2', //MB
clickable: false,
acceptedFiles: 'image/*',
createImageThumbnails: true,
thumbnailMethod: 'crop',
thumbnailWidth: 300,
thumbnailHeight: 300,
headers: {
  'x-csrf-token': $('meta[name="csrf-token"]').attr('content')
},
};

Dropzone.JSのイベント

Dropzone.jsには複数のイベントが用意されており、独自の処理を追加したり、または処理を取り除いたりして、プラグインの拡張を行うことができます。

方法1: Dropzone.jsの関数を使って行う

デモコードで使っていた、Dropzone.jsが標準として用意している方法です。

JavaScript
Dropzone.options.uploadWidget = {
  init: function() {
    this.on('success', function( file, resp ){
      ...
    });
  },
  ...
};

方法2: インスタンスを作成から

イベントの動作を細かくコントロールしたり、デフォルトで用意されている方法では対応できない人向けにインスタンスを作成して行う方法も用意されています。

インスタンス化のコードは冒頭で紹介しています。

ここではインスタンス化された場合のイベント追加のサンプルコードを紹介します。

JavaScript
var uploader = new Dropzone('#upload-widget');
uploader.on('success', function( file, resp ){
  ...
});

どんな時に使うの?

最もよく使うのは「success」イベントだともいます。

これはアップロードが成功したら実行されます。成功した時に追加処理を加えたい時に便利ですね。

ちなみ、コールバックとして2つの引数(file objectとXMLHttpRequest)を返してくれます。

その他にも「addedfile」イベントや「removefile」イベントなどもありますので、詳しく知りたい人は公式サイトで確認をお願いします。

イベント全一覧

動作サンプル

1つイベントを使ったサンプルコードを紹介しましょう。

アップロードされる画像のWidthまたはHeightが条件を満たしていなかった場合はアップロードを拒否します。

これは標準の機能では実装できません。下記の様にイベントとacceptを駆使します。

Output
HTML
<form id="upload-widget13" method="post" class="dropzone"></form>
JavaScript
Dropzone.options.uploadWidget13 = {
  url: '/upload',
  dictDefaultMessage: 'アップロードしたいファイルをこちらにドラッグ & ドロップで追加してください',
  init: function() {
    this.on('thumbnail', function(file) {
      if ( file.width < 1024 || file.height < 768 ) {
        file.rejectDimensions();
    }
    else {
      file.acceptDimensions();
    }
  });
},
accept: function(file, done) {
  file.acceptDimensions = done;
  file.rejectDimensions = function() {
    done('画像のサイズは少なくとも 幅: 1024 かつ 高さ: 768 以上なければなりません。');
  };
},
};

Dropzone.JSのデザイン変更

デザインの拡張性も大変優れています。CSSのルールについては直接ファイル(dropzone.css basic.css)を参照すると良いでしょう。

CDNなら下記です。

HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/basic.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/dropzone.css"/>

デフォルトのHTMLは下記の様になっています。

HTML
<div class="dz-preview dz-file-preview">
  <div class="dz-details">
    <div class="dz-filename"><span data-dz-name></span></div>
    <div class="dz-size" data-dz-size></div>
    <img data-dz-thumbnail />
  </div>
  <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
  <div class="dz-success-mark"><span>✔</span></div>
  <div class="dz-error-mark"><span>✘</span></div>
  <div class="dz-error-message"><span data-dz-errormessage></span></div>
</div>

まとめ

画像のアップロードに大変便利なフォームであることが理解いただけたと思いますが、実際のデータ保存にはサーバーサイドで別の実装が必要な点も覚えておきましょう。