LoginSignup
27
30

More than 5 years have passed since last update.

アップロード支援JSライブラリ「Fine Uploader」の必要最低限サンプル

Posted at

Fine Uploader は便利

Fine Uploader は他ライブラリへの依存がなく、高機能で主要ブラウザはもちろん、IE8+にも対応していて助かる。
助かるんだけど、機能がありすぎて少しとっつきにくいのが難でいつも忘れる。

ここでは、高機能っぷり発揮のデモほどのものは不要で、必要最低限でいいって時のサンプルをメモ。

「CORE」のみを利用

Fine Uploader には 基本機能(CORE)UI機能 というのがある。
UI機能は独自のテンプレートエンジンとか使って簡単にUI周りが作れるようなやつなんだけど、今回は割愛し、使うのはCOREの機能のみ。
(UI機能にはすべてのCORE機能が含まれる)

COREのみを利用する場合、インスタンスは以下のように作成する。

var uploader = new qq.FineUploaderBasic({
    // ...コンフィグ...
});

qq というのは Fine Uploader の本体オブジェクトで、qq という名前で決まってる(何の略かは知らんけど)。
jQueryでいう $ みたいなやつ。

ちなみにUI機能を使う時は FineUploaderBasic 部分が FineUploader (Basicがない) になる。

実現したい要件

今回は以下のような超シンプルなもの。

  • input type="file" ではなくボタンのクリックで画像ファイルを選択
  • 選択するとサムネイルをプレビュー
  • 送信ボタンでアップロード開始
  • アップロードできる拡張子を限定したい
  • 送信完了したらなにかしたい

コード

HTMLとCSS

HTMLとCSS部分
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>サンプル</title>
    <style>
    /* プレビュー画像のCSS */
    #preview {
        display: block;
        max-width:100px;
        max-height:100px;
        border:1px dashed #ddd;
    }
    </style>
</head>
<body>
    <button id="button">ファイル選択</button>
    <button id="upload">アップロード</button>

    <!-- プレビュー用画像 -->
    <img id="preview">
</body>
</html>

JavaScript

すべての CORE 用オプションは公式ドキュメントで
オプションに加え、用意されている drawThumbnailメソッドuploadStoredFilesメソッド も使用している。

JavaScript部分
// UI用の FineUploader でなく FineUploaderBasic を使用
var uploader = new qq.FineUploaderBasic({
  // 「送信」ボタンでアップロードするため false に
  autoUpload: false,

  // ファイル選択ボタン
  button: document.getElementById('button'),

  // 検証
  validation: {
    // アップロードできる拡張子を限定
    allowedExtensions: ['jpeg', 'jpg', 'gif', 'png']
  },

  // POST先
  request: {
    endpoint: location.href
  },

  // コールバックたち
  callbacks: {
    // エラーがあった時
    onError: function(id, filename, message, xhr) {
      alert(message);
    },

    // ファイルが選択された時
    onSubmit: function(id, filename) {
      // qq.FineUploaderBasic インスタンス
      var self = this;

      // drawThumbnail メソッドでプレビュー用画像に描画
      // (src 属性に data スキーマがセットされる)
      this.drawThumbnail(id, document.getElementById('preview'));

      // アップロードボタンにクリックイベントを付加
      document.getElementById('upload').addEventListener('click', function(e) {
        e.preventDefault();
        // クリックされたらアップロード開始
        self.uploadStoredFiles();
      }, false);
    },

    // アップロードが完了した時
    onComplete: function(id, filename, response, xhr) {
      alert('' + filename + '」のアップロード完了!');
    }
  }
});

全体

HTML全体
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>サンプル</title>
    <style>
    #preview {
        display: block;
        max-width:100px;
        max-height:100px;
        border:1px dashed #ddd;
    }
    </style>
</head>
<body>

    <button id="button">ファイル選択</button>
    <button id="upload">アップロード</button>
    <img id="preview">

<script src="https://cdnjs.cloudflare.com/ajax/libs/file-uploader/5.10.0/fine-uploader.min.js"></script>
<script>
var uploader = new qq.FineUploaderBasic({
  autoUpload: false,
  button: document.getElementById('button'),
  validation: {
    allowedExtensions: ['jpeg', 'jpg', 'gif', 'png']
  },
  request: {
    endpoint: location.href
  },
  callbacks: {
    onError: function(id, filename, message, xhr) {
      alert(message);
    },
    onSubmit: function(id, filename) {
      var self = this;
      this.drawThumbnail(id, document.getElementById('preview'));
      document.getElementById('upload').addEventListener('click', function(e) {
        e.preventDefault();
        self.uploadStoredFiles();
      }, false);
    },
    onComplete: function(id, filename, response, xhr) {
      alert('' + filename + '」のアップロード完了!');
    }
  }
});
</script>
</body>
</html>

これで要件を満たした。

とりあえず上記コードをCodePenで動作確認できるようにした
(送信すると500エラーが出るけど大丈夫)

サーバー側

サーバーへは XMLHttpRequest(Ajax) で送信されるけど、普通に multipart/form-data でアップロードされたようなデータが来る。
返却は JSON 形式にし、成功なら {"success": true} 、エラーなら {"success": false} または {"error": "メッセージ"} を返す。
(返す JSON には success error 以外のデータも含んでOK)

ちなみに Fine uploader の強力な機能に chunking がある。
これはアップロードファイルを分割して送信する機能で、例えばモバイル等でアップロード中に接続が切れても途中から再開(resume)できる。
また、エラー時にリトライできたりもするので便利。
chunking を使う場合の流れは

  1. JavaScriptで chunkingオプション を設定
  2. ファイル送信(自動で分割。非同期で順不同)
  3. サーバーで分割ファイルをひとつずつ一時保存(番号情報が来るので、その番号をファイル名にするといい)
  4. 完了したら一時ファイルを順番に結合(完了用のURLを別にしたり可)

みたいになる。
(chunking 時の分割ファイルの mime type は application/octet-stream になるので注意)

27
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
30