Edited at

Node.js (Express4)におけるmulterを使ったファイルのアップロード

More than 1 year has passed since last update.

Node.jsとExpress4の組み合わせでブラウザからサーバにファイルをアップロードする方法をWebで調べたところ、古い情報ばかり出てきて解決までに半日ほどかかりました。この記事では、Express4とmulterモジュールを使ったファイルのアップロード方法についてまとめてみます。

multerモジュールのREADMEを参考にさせていただきました。


前提条件

Expressのバージョンは4.13.4、multerモジュールのバージョンは1.2.0です。

$ express --version

4.13.4

$ npm list multer

xxxx@y.y.y zzzzz
└── multer@1.2.0


ファイルをアップロードするアプリケーションの作成

express-generatorを使って、アプリケーションの雛形を生成します。

$ express file-upload


create : file-upload
create : file-upload/package.json
create : file-upload/app.js
create : file-upload/public
create : file-upload/public/javascripts
create : file-upload/public/images
create : file-upload/public/stylesheets
create : file-upload/public/stylesheets/style.css
create : file-upload/routes
create : file-upload/routes/index.js
create : file-upload/routes/users.js
create : file-upload/views
create : file-upload/views/index.jade
create : file-upload/views/layout.jade
create : file-upload/views/error.jade
create : file-upload/bin
create : file-upload/bin/www

install dependencies:
$ cd file-upload && npm install

run the app:
$ DEBUG=file-upload:* npm start

続いて、package.jsonを編集してmulterモジュールを追加します。

{

"name": "file-upload",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.15.1",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"express": "~4.13.4",
"jade": "~1.11.0",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0",
"multer": "~1.2.0"
}
}


views/index.jade```を編集して、ファイルを選択してサーバにアップロードする画面を作成します。


```jade
extends layout

block content
h1= title
form(method="post", enctype="multipart/form-data", action="/upload")
input(type="file", name="thumbnail")
input(type="submit")


クライアントが発行するPOSTリクエストに応じてファイルをアップロードする処理を、routes/index.jsに加えます。

var express = require('express');

var router = express.Router();
var multer = require('multer');

var upload = multer({ dest: './uploads/' }).single('thumbnail');

/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});

router.post('/upload', function(req, res) {
upload(req, res, function(err) {
if(err) {
res.send("Failed to write " + req.file.destination + " with " + err);
} else {
res.send("uploaded " + req.file.originalname + " as " + req.file.filename + " Size: " + req.file.size);
}
});
});

module.exports = router;

multer({ dest: './uploads/' })で、ファイルのアップロード先のディレクトリを指定します。ファイルを一個だけアップロードする.single()メソッドを用いる場合、アップロードされたファイルのオブジェクトはreq.fileに格納されます。アップロードしたファイルの名前には、multerモジュールによりランダムな値が設定されます。アップロード前のファイル名はreq.file.orignalname、アップロード後のファイル名はreq.file.filenameから取得できます。その他、アップロード先のディレクトリをreq.file.destinationから、アップロードしたファイルのサイズをreq.file.sizeから取得することができます。


ファイルのアップロード

では、さっそくアプリケーションを起動してみましょう。

$ npm install

npm WARN deprecated jade@1.11.0: Jade has been renamed to pug, please install the latest version of pug instead of jade
npm WARN deprecated transformers@2.1.0: Deprecated, use jstransformer
cookie-parser@1.4.3 node_modules\cookie-parser
├── cookie-signature@1.0.6
└── cookie@0.3.1
...
$ npm start

> file-upload@0.0.0 start C:\Users\IBM_ADMIN\Documents\ITLMC\2016\blog\file-upload
> node ./bin/www

ブラウザでhttp://localhost:3000にアクセスします。

「参照」ボタンからファイルを選んで、送信ボタンを押すと。。。

アップロードの完了時にupload()メソッドに渡したコールバック関数が呼ばれて、サーバからレスポンスが返ってきました。IMG_4533.JPGという名前のファイルが2e491eefb9ec7c5858af2f0aba0ecee6という名前でアップロードされたようです。では、アップロード先として指定した./uploadsディレクトリの中を見てみましょう。

$ ls -l ./uploads/

合計 188
-rwx------+ 1 smatsui None 188729 9月 28 15:01 2e491eefb9ec7c5858af2f0aba0ecee6

ファイルをアップロードすることができました!