MDN express 学习笔记-本地图书馆

时间:2021-2-20 作者:admin

这是 MDN 上面的 node框架express 的教程,实现一个本地图书馆管理项目。

课程采用了服务端渲染,渲染模板引擎是pug, 数据库是mongoDB, 实现了增删改查。

我先把教程整体看过一遍,大体理解了,不过为了熟悉一点,逼着自己一步一步跟着做出来了。
这是我做的项目仓库地址

node Version: v12.18.3
npm Version: 6.14.8
mongoDB Version: v4.4.1

数据库用的是本地的mongoDB,所以如果你要跑起来看看效果,要先安装mongoDB 并启动它。


这个教程的编写是2016年,我练习时间是2020年,以下记录我在跟着教程走时遇到的问题

课程引入方式如下:

const { body,validationResult } = require('express-validator/check');
const { sanitizeBody } = require('express-validator/filter');

根据提示,现在建议使用的引入方式如下:

const { body,validationResult, sanitizeBody } = require("express-validator")
  • 旧的版本 express-validator 不支持在验证的时候转义请求的body数据,但是现在可以了,不用再分开 body 和 sannitizeBody 两部分走了

  • Express 教程 6: 使用表单 > 创建书本表单 这一节中,代码并没有处理 “用户不选择书本种类的情况”,导致写入数据库报错。(更新书本表单也是)

原教程代码如下(/controllers/bookController.js):

exports.book_create_post = [
    // Convert the genre to an array.
    (req, res, next) => {
        if(!(req.body.genre instanceof Array)){
            if(typeof req.body.genre==='undefined')
            req.body.genre=[];
            else
            req.body.genre=new Array(req.body.genre);
        }
        next();
    },

    // Validate fields.
    body('title', 'Title must not be empty.').isLength({ min: 1 }).trim(),
    body('author', 'Author must not be empty.').isLength({ min: 1 }).trim(),
    body('summary', 'Summary must not be empty.').isLength({ min: 1 }).trim(),
    body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim(),

    // Sanitize fields (using wildcard).
    sanitizeBody('*').trim().escape(),
    sanitizeBody('genre.*').escape(),
    // Process request after validation and sanitization.
    (req, res, next) => {

        // Extract the validation errors from a request.
        const errors = validationResult(req);

        // Create a Book object with escaped and trimmed data.
        var book = new Book(
          { title: req.body.title,
            author: req.body.author,
            summary: req.body.summary,
            isbn: req.body.isbn,
            genre: req.body.genre
           });

        if (!errors.isEmpty()) {
            // There are errors. Render form again with sanitized values/error messages.

            // Get all authors and genres for form.
            async.parallel({
                authors: function(callback) {
                    Author.find(callback);
                },
                genres: function(callback) {
                    Genre.find(callback);
                },
            }, function(err, results) {
                if (err) { return next(err); }

                // Mark our selected genres as checked.
                for (let i = 0; i < results.genres.length; i++) {
                    if (book.genre.indexOf(results.genres[i]._id) > -1) {
                        results.genres[i].checked='true';
                    }
                }
                res.render('book_form', { title: 'Create Book',authors:results.authors, genres:results.genres, book: book, errors: errors.array() });
            });
            return;
        }
        else {
            // Data from form is valid. Save book.
            book.save(function (err) {
                if (err) { return next(err); }
                   //successful - redirect to new book record.
                   res.redirect(book.url);
                });
        }
    }
];

添加了无选择 书本种类 情况的容错后代码如下(express-validador 自定义验证

  // Validate fields.
  body('title', 'Title must not be empty.').isLength({ min: 1 }).trim(),
  body('author', 'Author must not be empty.').isLength({ min: 1 }).trim(),
  body('summary', 'Summary must not be empty.').isLength({ min: 1 }).trim(),
  body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim(),
  // 在这一部分添加多一个自定义验证
  body('genre').custom(value => {
    if (!value.length) {
      return Promise.reject('Must select a genre')
    } 
    return true
  }),
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。