#はじめに
Node.jsでアプリ制作を始めようと思った矢先に画像ファイルのアップロードでつまづいたので書き残しておきます。
ExpressにはForm送信のためのモジュール「body-parser」が用意されていますが、これはメディアタイプ:multipart/form-dataに対応しておらず、ファイルをアップロードすることができないようです。そのため「multer」というモジュールを使う必要がありますが、これは逆にメディアタイプ:multipart/form-dataにしか対応していません。(以下URL参照)
Body-parserについて:http://info-i.net/express-body-parser
使い分けるのは面倒なので今回は「fileUpload」というモジュールを使います。
fileUploadについて:https://www.npmjs.com/package/express-fileupload
#モジュールのインストール
まずモジュールをインストールします。今回「fileUpload」によってPOSTで送られてきたファイルをサーバーに保存しておき、名前だけをDBに保存するという方式にします。呼び出すときはDBから名前を呼び出し、それに紐づいた画像をサーバーから取ってくるというシステムにします。
そのためサーバー上にデータを保存するためのモジュール「fs」もインストールしておきます。
また同名のファイルが送られてきた際に、画像ファイルの上書きされてしまうために画像の名前を書き換えます。その時に時刻を使うため時刻を表示するためのモジュール「date-utils」もインストールしておきます。
$ npm install --save fileUpload
$ npm install --save fs
$ npm install --save date-utils
#アプリ構成について
今回アプリの構成は下のようになっています
├── app.js
├── public
│ └── images
│ └── upload_icon //今回ここに画像ファイルを取り込みたい
├── views
│ └── mypage.ejs //今回画像ファイルを取り込むための画面ファイル
└── routes
└── mypage.js //今回画像ファイルを取り込むための実行ファイル
#各ファイルの修正
「app.js」に以下の文を書き足すします。
var fileUpload = require('express-fileupload');
app.use(fileUpload());
また「mypage.js」にも行き、以下の文を書き足します。
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
//今回追加したもの
require('date-utils');
var path = require('path');
var fs = require('fs');
//データベースのコンフィグ設定
var mysql_setting = {
host : ホスト名,
user : ユーザー名,
password : パスワード,
database : データベース名,
}
//画像がPOSTされた時の処理
router.post('/',(req,res)=>{
//変数準備
var id = req.session.login.id; //今回変更したいDBのカラムID
var now = new Date(); //画像名前変更のため日付を出しておく
var time = now.toFormat('YYYYMMDDHH24MISS')
//画像ファイル(アイコン)の拡張子を取り出し、時間とsession変数で名前をつけ直す。これによりuserが全く同じ名前のファイルをアップしてきても大丈夫
var icon_ext = path.extname(req.files.icon.name);
var new_iconname = time+req.files.icon.md5+icon_ext;
//画像ファイルを保存するパスを設定
var target_path_i = 'public/img/upload_icon/'+new_iconname;
//ファイルをサーバーに保存した後、ファイル名をDBの保存、今後ファイルを取り出す際はDBから名前を取ってきてサーバーに保存してある画像ファイルとひもづける
fs.writeFile(target_path_i, req.files.icon.data,(err) => {
if(err){
throw err
}else{
var data = {'icon':new_iconname};
var connection =mysql.createConnection(mysql_setting);
connection.connect();
connection.query('insert into テーブル名 set ?',data,
function(error,results,fields){
res.redirect('/mypage')
})
connection.end();
}
});
});
module.exports = router;
このようにしたところ画像をForm送信から取り込むことができました