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

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

```
npm install express-validator
```
# バリデーションを使う
以下を修正します。

```html: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>
```

```javascript: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');
    }
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/8cb60ac4-ec11-7006-7410-3c56d686e7d1.png)
以下のURLからバリデーションを確認できます。

http://localhost:3000/hello/add

# サニタイズ用メソッド
formの内容を保管し、表示する際にHTMLやJavaScriptの実行を防ぐため、以下のように修正します。

```javascript:routes/hello.js
router.post('/add', [
    check('name', 'NAME は必ず入力して下さい。').notEmpty().escape(),
    check('mail', 'MAIL はメールアドレスを記入して下さい。').isEmail().escape(),
    check('age', 'AGE は年齢(整数)を入力して下さい。').isInt()
],
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/fb4f1473-fc8e-9e42-6cfe-f7a1a4e4525f.png)
以下のはサニタイズ結果になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/f46d99f5-5acc-254a-b281-aaee1004cd58.png)

# カスタムバリデーション
一例として今回は年齢を入力範囲を指定します。
以下のように修正します。

```javascript: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;
    })
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/5df379f1-cd39-e3f8-fb9f-246c26ef8e62.png)

https://qiita.com/Glider2355/items/f3afa8f7c6c5bdd6831b