Node.js/ExpressJSでのファイルのアップロード

これも良く使う処理ですね。
expressコマンドで作成していきます。

$ express -e upload
$ cd upload && npm install

app.js

通常expressコマンドで作成されたapp.jsは以下の様になっています。

app.configure(function(){
	//...
	app.use(express.bodyParser());
	//...
});

これを以下の様に、アップロード先のディレクトリを指定するようにします。ルーティングの所も書いておきます。

var routes = {
	index  : require('./routes/index'),
	upload : require('./routes/upload')
};

app.configure(function(){
	//...
	app.use(express.bodyParser({uploadDir:'./uploads'}));
	//...
});

app.get('/', routes.index.index);
app.post('/upload', routes.upload.get);

uploadsディレクトリは、app.jsと同じ階層に作成します。

$ ls -F
app.js        package.json  routes/       views/
node_modules/ public/       uploads/

index.html

ビューは普通にフォームを作ります。

<form method="post" enctype="multipart/form-data" action="/upload">
	<input type="file" name="thumbnail">
	<input type="submit">
</form>

route/upload.js

アップロードされたファイルの情報はreq.filesから取得できます。
※public以下のimagesディレクトリは名前が長いので、imgにリネームしています。

var fs = require('fs');
exports.post = function(req, res){
	// 一時ファイルのパス
	var tmp_path = req.files.thumbnail.path;
	// public以下に置くパス
	var target_path = './public/img/' + req.files.thumbnail.name;
	// public以下に移動
	fs.rename(tmp_path, target_path, function(err) {
		if (err) throw err;
		// 一時ファイルを削除
		fs.unlink(tmp_path, function() {
			if (err) throw err;
			res.send('File uploaded to: ' + target_path + ' - ' + req.files.thumbnail.size + ' bytes');
		});
	});
};

と、普通のフォームでの実装はできましたが、今時単一のファイルだけを扱う場合以外に使う事もありませんので、ライブラリとか使った場合も試してみたいと思います。