#目的
Node.jsを用いて簡易なWebシステムを構築する。Node.jsで簡易なWebシステムの構築①のアプリの拡張で、今回はデータの登録を可能にする。
#環境条件
Node.jsで簡易なWebシステムの構築①で作業した環境をそのまま利用。
#構築手順
ec2-userでログイン
# rootユーザにスイッチ
sudo su -
##1.基本的な環境設定
#/opt/nodejsのディレクトリに移動
cd /opt/nodejs
express-generatorを用いてアプリケーションのベースを構築。
#expressのインストール
npm install express --save
npm WARN saveError ENOENT: no such file or directory, open '/opt/nodejs/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/opt/nodejs/package.json'
npm WARN nodejs No description
npm WARN nodejs No repository field.
npm WARN nodejs No README data
npm WARN nodejs No license field.
- express@4.17.1
added 50 packages from 37 contributors and audited 50 packages in 2.319s
found 0 vulnerabilities
#express-generatorのインストール
npm install -g express-generator
npm WARN deprecated mkdirp@0.5.1: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
/usr/local/bin/express -> /usr/local/lib/node_modules/express-generator/bin/express-cli.js
- express-generator@4.16.1
added 10 packages from 13 contributors in 0.715s
#myapp2という名前でアプリケーションのベースを構築
express -e myapp2
warning: option --ejs' has been renamed to
--view=ejs'
create : myapp2/
create : myapp2/public/
create : myapp2/public/javascripts/
create : myapp2/public/images/
create : myapp2/public/stylesheets/
create : myapp2/public/stylesheets/style.css
create : myapp2/routes/
create : myapp2/routes/index.js
create : myapp2/routes/users.js
create : myapp2/views/
create : myapp2/views/error.ejs
create : myapp2/views/index.ejs
create : myapp2/app.js
create : myapp2/package.json
create : myapp2/bin/
create : myapp2/bin/www
change directory:
$ cd myapp2
install dependencies:
$ npm install
run the app:
$ DEBUG=myapp2:* npm start
#myapp2ディレクトリに移動
cd myapp2/
#npmパッケージのインストール
npm install
npm notice created a lockfile as package-lock.json. You should commit this file.
added 54 packages from 38 contributors and audited 55 packages in 2.187s
found 0 vulnerabilities
#mysql関連ライブラリとexpress-validatorのインストール
npm install --save mysql express-validator
##2.アプリケーションの開発
今回のアプリケーションは、http://ホスト名:3000にアクセスすると[Node.jsで簡易なWebシステムの構築①](https://qiita.com/MARTOON/items/3a7a4cbd161d07c0ff20)と同様に商品(果物)リストが表示され、その画面上にボタンを追加し、当該ボタンから商品登録画面に遷移し、登録が完了すると、登録後の情報を元の画面を更新して表示するという仕様とする。遷移先のURLはhttp://ホスト名:3000/insertとする。
express-generatorで生成された各種ファイルに対し、追記や変更、ファイル追加を実施することで構築している。
- 追記・変更したもの
- public/stylesheets/style.css
- routes/index.js
- views/index.ejs
- 追加したもの
- views/insert.ejs
####routes/index.js
// 必要なライブラリの呼び出し
const express = require('express');
const router = express.Router();
const mysql = require('mysql');
const { check, validationResult } = require('express-validator/check');
// mysql接続用の設定定義
const mysql_setting = {
host: 'localhost',
user: 'root',
password: 'password',
database: 'myappdb'
}
// http://<hostname>:3000にアクセスがきた際のレスポンス
router.get('/', function(req, res, next) {
// DBコネクションの生成
const connection = mysql.createConnection(mysql_setting);
connection.connect();
// SQLの実行と結果の取得とindex.ejsへの伝達
connection.query('select * from myapptbl1', function (err, results, fields) {
if (err) throw err
res.render('index', { content: results })
});
// DBコネクションの破棄
connection.end();
});
// http://<hostname>:3000/insertにアクセスがきた際のレスポンス(insert.ejs)
router.get('/insert', function (req, res, next) {
const data = {
errorMessage: ''
}
res.render('./insert', data);
});
// http://<hostname>:3000/insertへアクセスが来た際のレスポンス
// web画面上で入力された値が空になっていないかを確認し、エラーメッセージを表示
router.post('/insert', [check('name').not().isEmpty().trim().escape().withMessage('名前を入力して下さい'),check('price').not().isEmpty().trim().escape().withMessage('値段を入力して下さい'),], (req, res, next) => {
const errors = validationResult(req);
// 値が空の場合
if (!errors.isEmpty()) {
const errors_array = errors.array();
res.render('./insert', {
errorMessage: errors_array,
})
} else {
// 値が入力されている場合
// 画面上で入力された値を変数として定義
const name = req.body.name;
const price = req.body.price;
// SQL用に配列の作成と変数の入力
const post = { 'name': name, 'price': price };
// DBコネクションの生成
const connection = mysql.createConnection(mysql_setting);
connection.connect();
// プレースホルダを用いてSQLを発行し、データを登録する
connection.query('INSERT INTO myapptbl1 SET ?', post, function (error, results, fields) {
if (error) throw error;
// http://<ホスト名>:3000にリダイレクト(Insert後のデータを出力)
res.redirect('./');
console.log('ID:', results.insertId);
});
// DBコネクションの破棄
connection.end();
}
})
module.exports = router;
以下、ejsファイルは大したこと書いてないので、細かい説明は割愛
####views/index.ejs
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<table>
<thead>
<tr>
<th scope="col">id</th>
<th scope="col">name</th>
<th scope="col">price</th>
</tr>
</thead>
<% for(let i in content) { %>
<tr>
<% let obj = content[i]; %>
<th>
<%= obj.id %>
</th>
<th>
<%= obj.name %>
</th>
<th>
<%= obj.price %>
</th>
</tr>
<% } %>
</table>
<p class="bottom_space"></p>
<button class="b1" onclick="location.href='./insert'">商品登録画面</button>
</body>
</html>
####views/insert.ejs
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<p class="p1">商品を登録してください</p>
<form action="/insert" method="post">
<input type="text" name="name" value="名前">
<input type="text" name="price" value="値段">
<button class="b2">登録</button>
</form>
<% if(errorMessage) { %>
<ul>
<% for (let n in errorMessage) { %>
<li>
<%= errorMessage[n].msg %>
</li>
<% } %>
</ul>
<% } %>
</body>
</html>
最低限の見栄えのために以下追記
(aタグまではデフォルト)
####public/stylesheets/style.css
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
table, tr, th {
border-collapse: collapse;
border:1px solid;
font-size: 30px;
}
th {
width: 400px;
height: 50px;
}
table thead tr th {
color: #fff;
background: #000000;
}
.bottom_space {
margin-bottom: 1em;
}
.b1 {
width: 1204px;
height: 50px;
font-size: 30px;
}
.b2 {
width: 400px;
height: 50px;
font-size: 30px;
}
.p1 {
font-size: 50px;
}
input {
width: 400px;
height: 50px;
font-size: 30px;
}
##3.画面イメージ
###http://<ホスト名>:3000
###http://<ホスト名>:3000/insert
###値の入力
###登録後のリダイレクト