express4でexpress-flashの利用
(npm)express-flash:https://www.npmjs.com/package/express-flash
node.jsのフレームワークexpress 4でのflash、express-flashの利用についてのメモ書き程度。
ある日、サンプルのWebページを作ろうかなと思って express と express-flash をインストールして立ち上げてみようと思ったらエラーが・・・。
$ node app.js
project/node_modules/express/lib/express.js:112
throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
・・・
え、今までこれで動いてたやん!
npmのexpress-flashのところに書いてあるとおりにしたよ!!
とワタワタしていたら、いつまにか express の(メジャー)バージョンが4に上がっていて、いくつか使えなくなっている関数やらが出てきたようで。。
教訓: バージョンはしっかり確認しよう!
さて、そんなわけで、express 4をインストールすると、express-flashのサイトに書いてあるサンプルの通りだと動かないわけで、expreess 4での書き方をメモっておきます。
まず、必要モジュールのインストール
npm install express # v4.17.1 (2019/12/16現在)
npm install express-flash # v0.0.2 (2019/12/16現在)
npm install express-session # 新たに必要になったもの1
npm install cookie-parser # 新たに必要になったもの2
# あとはテンプレートエンジン(※ 他のを使う場合は適宜置き換えてください)
npm install ejs
サイト作成
アイテム(名)を追加していくサイト。
同じ名前のアイテムを追加しようとするとエラーを表示するサイトにしました
app.jsのポイント
- express.cookieParser → cookieParser に
- express.session → session に
resave、saveUninitialized、secretの引数は必須
app.js
'use strict';constexpress=require("express");// express-flashを使うためのもろもろconstflash=require('express-flash');constsession=require('express-session');constcookieParser=require('cookie-parser');// http処理、POST処理などに利用constpath=require('path');consthttp=require('http');constbodyParser=require('body-parser');constapp=express();// テンプレート、静的ファイルの配置app.set('view engine','ejs');app.use(express.static(path.join(__dirname,'public')));app.use(bodyParser.urlencoded({extended:true}));app.use(bodyParser.json());// **********************************// express-flashのサンプルに合わせて//app.use(express.cookieParser('keyboard cat'));app.use(cookieParser('keyboard cat'));//app.use(express.session({ cookie: { maxAge: 60000 }}));app.use(session({resave:true,saveUninitialized:true,secret:'rAnd0m',cookie:{maxAge:60000}}));app.use(flash());// **********************************letg_item_list=[];// indexapp.get('/',async(req,res,next)=>{res.render('index');});// アイテム追加ページapp.get('/item_add',async(req,res,next)=>{res.render('item_add');});// アイテム追加実行app.post('/item_add_exec',async(req,res,next)=>{letitem_name=req.body.item_name;constfind=g_item_list.find((val)=>{return(val===item_name);});if(find!==undefined){req.flash('err','すでに同じアイテムが登録されています');returnres.render('item_add');}// アイテム(名)追加g_item_list.push(item_name);req.flash('success','アイテム登録しました');res.redirect('/');});constport=(process.env.PORT!==undefined)?process.env.PORT:3000;constserver=http.createServer(app).listen(port,()=>{console.log('Server running at http://127.0.0.1:'+port+'/');});
テンプレートのポイント
成功した(successにセットされた)Flash文言があればこれで表示
<% if(messages.success){ %>
<div class="alert alert-success" role="alert"><%=messages.success %></div><br/>
<% } %>
失敗した(errにセットされた)Flash文言があればこれで表示
<% if(messages.success){ %>
<div class="alert alert-success" role="alert"><%=messages.success %></div><br/>
<% } %>
views/index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>サンプル</title>
</head>
<body>
<div class="container">
<h2>サンプル</h2>
<% if(messages.success){ %>
<div class="alert alert-success" role="alert"><%=messages.success %></div><br/>
<% } %>
<a href="/item_add">アイテム追加</a><br/>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
views/item_add.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>サンプル</title>
</head>
<body>
<div class="container">
<h2>アイテム追加</h2>
<% if(messages.err){ %>
<div class="alert alert-danger" role="alert"><%=messages.err %></div><br/>
<% } %>
<form action='/item_add_exec' method="POST">
<div class="form-group">
<label>アイテム名</label><br/>
<input type="text" name="item_name" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" name="submit" value="登録" />
</div>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
動作確認
構成はこのようになっているはず
node_modules/
views/
index.ejs
item_add.js
app.js
package-lock.json
package.json
起動
node app.js