読者です 読者をやめる 読者になる 読者になる

ボクココ

サービス開発を成功させるまでの歩み

HTML5 時代のファイルアップロード方法

JavaScript

ども、@kimihom です。

今までファイルのアップロードといえば、 input type="file" な要素を作って、 multipart なフォームで送信、というやり方が一般的だった。が、最近はAWSやHTML5の登場により、よりクールで使いやすいファイルアップロードを実現できるようになっている。

今回はその方法をご紹介したい。

File API によるファイル選択とドラッグアンドドロップ

最近のウェブサービスなら一般的になりつつあるファイルのドラッグアンドドロップ。今後は むしろドラッグ&ドロップのないサイトは古臭いし使いにくい というような所まで一般的な方法となるだろう。最近は HTML5 の提供する API のおかげでとても簡単に実装できるようになっている。

ファイル選択とドラッグ&ドロップの両方でキーになってくるのが、Fileオブジェクト。どちらの手法でやっても最終的に得られるのが File オブジェクトになる。

まずはファイル選択から見ていこう。

ファイル選択で File オブジェクトを取得

ファイル選択は、一般的な input type="file" なフォームを作って、そのchangeイベントを取得すると、Fileオブジェクトを取得できる。

  $(document).on("change", ".image-field .file-upload", function(e) {
    var file = e.target.files[0];
    // file オブジェクトが取得できた
  });

ファイルを複数選択した場合は配列で files が格納されているので、1つ1つ処理していけばよいことになる。

ドラッグ&ドロップで File オブジェクトを取得

続いてドラッグ&ドロップ。drop をはじめとした見慣れないイベントを定義してあげる。 dragover はファイルが対象のエリアに入った時点で呼ばれるイベント、dragleaveはファイルが対象のエリアから外れた時点で呼ばれるイベントである。

  // body dragover
  $(document).on("dragover", "body", function(e) {
    e.preventDefault();
    $(".image-field .droparea").addClass("droppable");
  });
  // body draglave
  $(document).on("dragleave", "body", function(e) {
    e.preventDefault();
    $(".image-field .droparea").removeClass("droppable");
  });
  // imagefield dragover
  $(document).on("dragover", ".image-field .droparea", function(e) {
    e.preventDefault();
    $(".image-field .droparea").addClass("hover");
  });
  // imagefield dragleave
  $(document).on("dragleave", ".image-field .droparea", function(e) {
    e.preventDefault();
    $(".image-field .droparea").removeClass("hover");
  });
  // imagefield drop
  $(document).on("drop", ".image-field .droparea", function(e) {
    e.preventDefault();
    $(".image-field .droparea").removeClass("hover droppable");
    var file = e.originalEvent.dataTransfer.files[0];
    // file オブジェクトが取得できた
  });

たくさんイベントを定義したが、大事なのは一番最後の drop イベントだけだ。他は UI をよくするためだけのイベント定義となっている。なぜ body にも dragover, dragleave イベントを定義しているのかというと、後察知の通り画面に画像などを持ってきた時にここにドロップしてね!とより視覚的に分かりやすくするためである。もちろん Slack のように body 全体をドロップできるようにしてもよいだろう。

e.preventDefault() はとても重要だ。これを書かないと画像だけがブラウザに表示されるようになってしまう。

ファイルをアップロード

あとは Amazon S3 にファイルを直接アップロードしよう。アップロード方法の詳細に関しては、以下に記述してある。 Amazon Cognito を用いたファイルアップロード方法だ。

www.selfree.co.jp

より発展的な実装

それでは画像を縮小させる、クロップ(縦横比を合わせる)にはどうすればいいか。

縮小に関しては AWS Lambda を使って、 S3 にアップロードしたタイミングをトリガとして、AWS 側で縮小させる方法がある。これに関しては別記事に譲るとして、クロップに関しては今度書く記事でご紹介したいと思う。

あわせて読みたい

www.bokukoko.info

www.bokukoko.info

終わりに

HTML5のおかげでファイル操作が非常に簡単に行えるようになってきた。ファイルアップロードは File API を用いて実装することが一般的になってくるだろうから、ぜひここで基本を抑えておきたいところだ。