node.js超入門ノート7(バリデーション編)


準備

以下のコマンドでパッケージをインストールします。

npm install express-validator

バリデーションを使う

以下を修正します。

views/hello/add.ejs
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="content-type" content="text/html">
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css" />
    </head>

    <body class="container">
        <header>
            <h1 class="display-4">
                <%= title %>
            </h1>
        </header>
        <div role="main">
                <p><%- content %></p>
                <form action="/hello/add" method="post">
                    <div class="form-group">
                        <label for="name">NAME</label>
                        <input type="text" name="name" id="name" value="<%= form.name %>" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="mail">MAIL</label>
                        <td><input type="text" name="mail" id="mail" value="<%= form.mail %>" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="age">AGE</label>
                        <td><input type="number" name="age" id="age" value="<%= form.age %>" class="form-control">
                    </div>
                    <input type="submit" value="作成" class="btn btn-primary">
                </form>
        </div>
    </body>
</html>
routes/hello.js
const { check, validationResult } = require('express-validator');

router.get('/add', (req, res, next) => {
    var data = {
        title: 'Hello/Add',
        content: '新しいレコードを入力:',
        form: {name:'', mail:'', age:0}
    }
    res.render('hello/add', data);
});

router.post('/add', [
    check('name', 'NAME は必ず入力して下さい。').notEmpty(),
    check('mail', 'MAIL はメールアドレスを記入して下さい。').isEmail(),
    check('age', 'AGE は年齢(整数)を入力して下さい。').isInt()
], (req, res, next) => {
    const errors = validationResult(req);

    if (!errors.isEmpty()) {
        var result = '<ul class="text-danger">';
        var result_arr = errors.array();
        for(var n in result_arr) {
            result += '<li>' + result_arr[n].msg + '</li>'
        }
        result += '</ul>';
        var data = {
            title: 'Hello/Add',
            content: result,
            form: req.body
        }
        res.render('hello/add', data);
    } else {
        var nm = req.body.name;
        var ml = req.body.mail;
        var ag = req.body.age;

        db.serialize(() => {
            db.run('insert into mydata (name, mail, age) values (?, ?, ?)', nm, ml, ag);
    });
    res.redirect('/hello');
    }
});


以下のURLからバリデーションを確認できます。

サニタイズ用メソッド

formの内容を保管し、表示する際にHTMLやJavaScriptの実行を防ぐため、以下のように修正します。

routes/hello.js
router.post('/add', [
    check('name', 'NAME は必ず入力して下さい。').notEmpty().escape(),
    check('mail', 'MAIL はメールアドレスを記入して下さい。').isEmail().escape(),
    check('age', 'AGE は年齢(整数)を入力して下さい。').isInt()
],


以下のはサニタイズ結果になります。

カスタムバリデーション

一例として今回は年齢を入力範囲を指定します。
以下のように修正します。

routes/hello.js
router.post('/add', [
    check('name', 'NAME は必ず入力して下さい。').notEmpty().escape(),
    check('mail', 'MAIL はメールアドレスを記入して下さい。').isEmail().escape(),
    check('age', 'AGE は年齢(整数)を入力して下さい。').isInt(),
    check('age', 'AGE はゼロ以上120以下ので入力ください。').custom(value =>{
        return value >= 0 & value <= 120;
    })