世界一シンプル!drag&dropでファイルアップロードする。ExpressとMulterとDropzoneを使おう!
こんにちは!
週末は趣味でプログラミングするのでコロナだろうとコロナで無かろうと外出自粛になってしまう、しずかなかずしです。
JavaScriptのプログラミングで困ってませんか?
以前は、PythonでDjangoフレームワークを使ってWebアプリケーションを書いていました。Djangoの記事は、こちらの記事がおすすめです。通常はWordPress、つまりPHPを実行させて使われることが多いレンタルサーバー(エックスサーバー)ですが、Pythonのアプリも動かせるよ、という奮闘記です。
しかし、最近は、Nodejs と Expressフレームワークが手放せません。
今日は、ちょっとした備忘録的に、NodejsのExpressの上で、ファイルをドラッグ&ドロップしてアップロードする、世界一短いWebプログラムを書いてみます。
フレームワーク:Express
今回は、クライアントもサーバーもJavaScriptを使っていきます。
サーバーサイドのJavaScriptと言えば、言わずと知れたNodejsですね。今やその筋の人からすると「鬼滅の刃」と同じくらい有名なので当然ご存知でしょう。
そして、NodejsでWebアプリを作る場合は、フレームワークとしてはExpressが流行りです。
という訳で、今回のプログラミングはExpressを使っていきます。
Expressを使い始めるためには、Express generatorというツールを使うと、Webアプリケーションの雛形を作ってくれるので非常に便利です。
今日は本題ではないので、使い方は以下のサイトの記事に委ねます。
クライアント: Dropzone
本題のドラッグ&ドロップをWebアプリで実現するためのクライアントに選んだのは、dropzoneです。
dropzoneはクライアント用のJavaScriptライブラリです。Viewの表示やプログレスバー、アップロード画像のサムネールなど、Webブラウザでドロップ画面を表示を簡単に実装できます。
使い方は簡単。サイトからzipファイルをダウンロードしてきて、そのdistディレクトリにある「dropzone.js」および「dropzone.css」を見つけます。それらを、WebアプリをExpress generatorで生成した時にできる public フォルダにコピーしておきます。
後は、サーバーに設置した.jsファイルと.cssファイルをブラウザが読み込めるように、PUGの layout.pugファイルを以下のように記載します。
PUGはExpressで使うテンプレートエンジンの一つです。この言語でWebアプリのViewを記述すると実行時にレンダリングされて最終的にはHTMLがWebブラウザに送られます。
(6行目と7行目が追加したコードです)
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel='stylesheet', href='dropzone/dropzone.css')
script(src='dropzone/dropzone.js')
ブラウザに表示されるときのHTMLのコードは以下の通り。
<link rel="stylesheet" href="dropzone/dropzone.css">
<script src="dropzone/dropzone.js"></script>
※ jsファイル、cssファイルのパスは適切なものにして下さい。
そして、HTMLでドラッグ&ドロップのターゲットの「枠」を表示するのは以下のコードです。
同様にPugのコードはこちら(p Welcome to #{title}まではgeneratorが作ったコードです)。
extends layout
block content
h1= title
p Welcome to #{title}
#awesome.dropzone
script(type='text/javascript').
var myDropzone = new Dropzone("div#awesome", { url: "/upload"});
私が追加したのは、最後の3行。 DIV要素(idは’awesome’)の追加と、JavaScriptのコード(new Dropzone()の実装)です。
これがレンダリングされるとHTML(一部)はとしては以下のように出力されます。
<div class="dropzone" id="awesome"></div>
<script type="text/javascript">
var myDropzone = new Dropzone("div#awesome", { url: "/upload"});
</script>
アップロードするサーバー側のパスは「/upload」にしています(url:で指定されている)。
このパスは、Expressのサーバーが側のRouterの実装(後述)と合せておく必要があります。
サーバー: Multer
dropzoneだけだと、サーバー側の処理がないので、Expressのサーバー側の処理を実装します。
Multer というライブラリを使用しました。Multerは、HTMLのマルチパートのフォーム形式のファイルアップロードを処理するNodejsのライブラリです。マルチーパートだからmulterなんですね、きっと。
インストールは簡単。コマンドラインで以下を実行するだけ。
$ npm install multer –save
upload.jsというRouterクラスを1つ実装しました。
わずか10行のクラスです。
var express = require('express');
var router = express.Router();
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
router.post('/', upload.single('file'), function(req, res) {
console.log("originalname:" + req.file.originalname + ", filename:" + req.file.filename + ", size: " + req.file.size);
res.end();
});
module.exports = router;
dest: 'uploads/’がサーバー上で、アップロードされたファイルを格納すされるディレクトリです。
postで受けて、req.file.filenameに、uploadsに格納されたファイル名(ファイル名のみ)が入ります。ファイルの保存は全てmulterがやってくれる訳ですね。そして、サーバー上のファイルはかぶらないように自動的にランダムなファイル名をつけてくれます。req.file.fienameに入るのはそのファイル名です。
なんと便利なのでしょう!!
このクラス(Router)を使うために、generatorが生成したapp.jsも編集しましょう。
var uploadRouter = require('./routes/upload');
...
app.use('/upload', uploadRouter);
※ 追加したコードのみ記載しています。
app.use()で指定するパスが、dropzoneのライブラリのurl:で指定したパスになっていることに注意。これがすなわち、Webアプリの「ルーティング」という作業ですね。
結果の画面
完成したのがこちら。
めちゃめちゃ少量のコードで実現できて驚きます。めちゃめちゃ便利です。
NodejsやExpressをもっと知りたい方はこちら↓