Nodejs フォームの検証と画像のアップロード

php中世界最好的语言
リリース: 2018-03-16 13:52:13
オリジナル
1406 人が閲覧しました

今回は、Nodejs フォーム検証と画像アップロードについて説明します。次は、Nodejs フォーム検証と画像アップロードを使用する際の注意点です。 1. フォーム検証

MVC フォーム検証を実行できる場所は 3 つあり、最初のレベルはフロントエンドによる送信前、2 番目のレベルはデータが保存される前、つまりコントローラーで検証が行われます。 3 番目のレベルはデータを保存するときです。つまり、送信されたデータ モデルがエンティティによって定義された制約に準拠していない場合、データは保存できません。これは最後の防御線です。最初のレベルは主に js または jquery フレームワークに依存し、より一般的に使用されるのは jquery.validate.js です。 Asp.net MVC が

検証ルール

を自動的に生成できるかどうかについては、ここでは詳しく説明しません。インターネット上には多くの記事があります。 2 番目の層はそれぞれのビジネス ロジックに関連しており、フロントエンドによる JavaScript の禁止や不正なデータの送信を防ぐために必要な検証も必要です。ここでは Mongoose に基づく 3 番目の層の検証について説明します。 1. モデル定義を確認します

まず、Mongoose で以前に定義したブック モデルを確認しましょう。

var bookSchema = new mongoose.Schema({
    title: { type: String, required: true },
    rating: {
        type: Number,
        required: true,
        min: 0,
        max: 5
    },
    info: { type: String, required: true },
    img: String,
    tags: [String],
    brief: { type: String, required: true },
    ISBN: String,
});
ログイン後にコピー

各属性は、最小値、最大値、デフォルト値、その他の制約を追加することもできます。送信されたモデルがこれらの制約を満たしていない場合、正常に保存されません。 Asp.net MVC の DataAnnotations の役割と同等です。後続のフォーム検証はこれに基づいて行われます。

2. ルーティングを追加します

追加用に 2 つ (取得 1 つ、投稿 1 つ)、削除用に 1 つ、写真のアップロード用に 1 つ、計 4 つのルーティング ルールを追加する必要があります:

router.get('/book/create', homeController.bookcreateview);
router.post('/book/create', homeController.doBookCreate);
router.delete('/book/:id', homeController.delete);
router.post('/uploadImg', homeController.uploadImg);
ログイン後にコピー

高速ルーティングに基づいて、Restful ルーティングを作成できます。ルール。ルートは app_server フォルダーの下にあります。

3.

controller

メソッドを追加しますhome.bookcreateview:

module.exports.bookcreateview = function (req, res) {
    res.render('bookCreate', { title: '新增推荐图书' });
};
ログイン後にコピー

これは直接getリクエストなので、当然、このbookCreateビューが次に作成されます。

doBookCreate:

module.exports.doBookCreate = function (req, res) {    var requestOptions, path, postdata;
    path = "/api/book";
    postdata = {
        title: req.body.title,
        info: req.body.info,
        ISBN: req.body.ISBN,
        brief: req.body.brief,
        tags: req.body.tags,
        img: req.body.img,
        rating:req.body.rating,
    };
    requestOptions = {
        url: apiOptions.server + path,
        method: "POST",
        json: postdata,
    };
    request(requestOptions, function (err, response, body) {
        console.log("body.name", body.name, response.statusCode);        if (response.statusCode === 201) {
            res.redirect("/detail/"+body._id);
        } 
        else if (response.statusCode == 400 && body.name && body.name == "ValidationError") {
            res.render('bookCreate', { title: '新增推荐图书', error:"val"});
        }        else {
            console.log("body.name",body.name);
            info(res, response.statusCode);
        }
    });
};
ログイン後にコピー

info:

function info (res, status) {    var title, content;    if (status === 404) {
        title = "404, 页面没有找到";
        content = "亲,页面飞走了...";
    } else if (status === 500) {
        title = "500, 内部错误";
        content = "尴尬...,发生错误";
    } else {
        title = status + ", 有什么不对劲";
        content = "某些地方可能有些错误";
    }
    res.status(status);
    res.render('info', {
        title : title,
        content : content,
        status: status,
    });
};
ログイン後にコピー
コードを見る

前のセクションでは、データ操作の API 部分を作成しました。コードの処理としては、まずフロントエンドから渡されたデータをreqから取得し、リクエストモジュールを使ってAPIを呼び出し、追加が成功した場合(

ステータスコード

が201)に戻ります。詳細ページ。検証に失敗すると元のルートに戻り、ヒントが表示されます。エラーが発生した場合は、info メソッドに処理を任せます。 delete:

module.exports.delete = function (req, res) {    var requestOptions, path;
    path = "/api/book/" + req.params.id;
    requestOptions = {
        url: apiOptions.server + path,
        method: "delete",
        json: {},
    };
    request(requestOptions, function (err, response, body) {        if (response.statusCode == 204) {
            res.json(1);
        } 
        else {
            res.json(0);
        }
    });
};
ログイン後にコピー

削除が成功した場合、返されるステータス コードは 204 であり、その後 json(1) を返してフロントエンドにインターフェイスを処理させます。

4. ビューを追加します

1) まず、書籍リストの右側のサイドバーにボタンを追加する必要があります:

書籍ビューで変更:

   .col-md-3
     .userinfo
       p stoneniqiu
       a(href='/book/create').btn.btn-info 新增推荐
ログイン後にコピー

ユーザーがクリックするとジャンプします/book/create ページに

2) 新しい推奨ページを追加します:

extends layout
include _includes/rating
block content
  .row
   .col-md-12.page.bookdetail
      h3 新增推荐书籍  
      .row
        .col-xs-12.col-md-6
         form.form-horizontal(action='',method="post",role="form")          - if (error == "val")
           .alert.alert-danger(role="alert") All fields required, please try again
          .form-group
            label.control-label(for='title') 书名
            input#name.form-control(name='title')
          .form-group
            label.control-label(for='info') 信息
            input#name.form-control(name='info')            
          .form-group
            label.control-label(for='ISBN') ISBN
            input#name.form-control(name='ISBN')
          .form-group
            label.control-label(for='brief') 简介
            input#name.form-control(name='brief')
          .form-group
            label.control-label(for='tags') 标签
            input#name.form-control(name='tags')
          .form-group
            label.control-label(for='rating') 推荐指数
            select#rating.form-control.input-sm(name="rating")
              option 5
              option 4
              option 3
              option 2
              option 1
          .form-group
            p 上传图片
            a.btn.btn-info(id="upload", name="upload") 上传图片
            br
            img(id='img')
          .form-group
            button.btn.btn-primary(type='submit') 提交
ログイン後にコピー

写真のアップロードのエラー プロンプトを表示するために if ステートメントが使用されます。これについては後で詳しく説明します。そのため、送信ページは基本的に次のようになります。

3) Mongoose 検証

this フロントエンド検証はなく、フォームを直接送信できます。しかし、ノードはエラー ログを出力し、書籍の検証が失敗し、検証が失敗しました。

これは、Mongoose から返された検証情報です。この時点で、インターフェイスにプロンプ​​ト メッセージが表示されます。

これは、コントローラーでの処理によるものです。

  else if (response.statusCode == 400 && body.name && body.name == "ValidationError") {
            res.render('bookCreate', { title: '新增推荐图书', error:"val"});
        }
ログイン後にコピー

以上说明了Mongoose会在数据保存的时候验证实体,如果实体不满足path规则,将不能保存。但至此有三个问题,第一个问题是提示信息不明确,当然我们可以遍历输出ValidatorError;第二个就是,验证错误之后,页面原来的数据没有了,需要再输入一遍,这个我们可以参考Asp.net MVC将模型数据填充到视图中可以解决;第三个问题就是页面前端还没有验证,form直接就可以提交了,这个可以通过简单的Jquery脚本就可以做到;这三点先不细究。继续往下看,如果规范输入,这个时候是可以提交的,提交之后在books页面可以看到:

 

4)删除

在标题的右侧增加了一个删除符号(books视图中):

         .col-md-10
            p
             a(href="/Detail/#{book._id}")=book.title             span.close(data-id='#{book._id}') ×
ログイン後にコピー

并添加脚本:

$(".close").click(function() {    if (confirm("确定删除?")) {        var id = $(this).data("id");        var row = $(this).parents(".booklist");
        $.ajax({
            url: "/book/" + id,            method: "delete",
        }).done(function(data) {
            console.log(data);
            row.fadeOut();
        });
    }
});
ログイン後にコピー

脚本可以先位于layout视图下方:

  script(src='/javascripts/books.js')
ログイン後にコピー

这样,删除完成之后会隐藏当前行。下面解决图片上传问题。

二、图片上传

前面我们在路由里面定义了一个uploadimg方法,现在实现它。一般都涉及两个部分,一个是前台图片的提交,一个是后端数据的处理。

1.uploadimg 方法实现

先需要安装formidable模块。

然后在Public文件下创建一个upload/temp文件夹

脚本:

var fs = require('fs');var formidable = require('formidable');
module.exports.uploadImg = function (req, res) {  var form = new formidable.IncomingForm();   //创建上传表单
      form.encoding = 'utf-8';        //设置编辑
      form.uploadDir = './../public/upload/temp/';     //设置上传目录
      form.keepExtensions = true;     //保留后缀
      form.maxFieldsSize = 3 * 1024 * 1024;   //文件大小
    form.parse(req, function(err, fields, files) {
        console.log(files);        if (err) {
            console.log(err);          return res.json(0);        
        }        for (var key in files) {
            console.log(files[key].path);            var extName = ''; //后缀名
            switch (key.type) {            case 'image/pjpeg':
                extName = 'jpg';                break;            case 'image/jpeg':
                extName = 'jpg';                break;            case 'image/png':            case 'image/x-png':            default:
                extName = 'png';                break;
            }            var avatarName = (new Date()).getTime() + '.' + extName;            var newPath = form.uploadDir + avatarName;            
            fs.renameSync(files[key].path, newPath); //重命名
            return res.json("/upload/temp/"+ avatarName);
        }
    });
 
};
ログイン後にコピー

这个form会自动将文件保存到upLoadDir目录,并以upload_xxxx格式重新命名,所以最后使用fs模块对文件进行重命名。然后返回给前端。

2.前端

我喜欢用插件,前端我用的是plupload-2.1.8,拥有多种上传方式,比较方便。放置在Public文件下。在layout.jade中引用js:

   script(src='/plupload-2.1.8/js/plupload.full.min.js')
   script(src='/javascripts/books.js')
ログイン後にコピー

而在bookCreate.jade视图中,修改如下:

            a.btn.btn-info(id="upload", name="upload") 上传图片
            br            img(id='img')
            input#imgvalue(type='hidden',name='img',value='')
ログイン後にコピー

a标签用来触发上传,img用来预览,input用来存放路径。在books.js下增加以下代码:

var uploader = new plupload.Uploader({
    runtimes: 'html5,flash,silverlight,html4',    browse_button: "upload",    url: '/uploadImg',
    flash_swf_url: '/plupload-2.1.8/js/Moxie.swf',
    silverlight_xap_url: '/plupload-2.1.8/js/Moxie.xap',
    filters: {
        max_file_size: "3mb",
                mime_types: [
                    { title: "Image files", extensions: "jpg,gif,png" },
                    { title: "Zip files", extensions: "zip" }
                ]
    },
    init: {
        PostInit: function () {
        },
        FilesAdded: function (up, files) {
            plupload.each(files, function (file) {
                uploader.start();
            });
        },
        UploadProgress: function (up, file) {
        },
        Error: function (up, err) {
        }
    }
});
uploader.init();
uploader.bind('FileUploaded', function (upldr, file, object) {    var data = JSON.parse(object.response);
    console.log(data);    $("#img").attr("src", data);
    $("#imgvalue").val(data);});
ログイン後にコピー

提交:

 上传成功后跳转到detail页面。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

JavaScript的事件管理

jQuery、Angular、node中的Promise详解

JS里特别好用的轻量级日期插件

JavaScript关于IE8兼容问题的处理

以上がNodejs フォームの検証と画像のアップロードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート