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
1) 「アイテム追加」を押下
Image may be NSFW.
Clik here to view.
2) 新規アイテムなら
Image may be NSFW.
Clik here to view.
3) 同じアイテム名を登録しようとすると
Image may be NSFW.
Clik here to view.