>  기사  >  웹 프론트엔드  >  Nodejs 양식 확인 및 이미지 업로드

Nodejs 양식 확인 및 이미지 업로드

php中世界最好的语言
php中世界最好的语言원래의
2018-03-16 13:52:131396검색

이번에는 Nodejs 폼 검증 및 이미지 업로드에 대해 알려드리겠습니다. Nodejs 폼 검증 및 이미지 업로드 시 주의할 점은 무엇인가요? 1. 양식 확인

MVC 양식 확인을 수행할 수 있는 곳은 세 곳이 있습니다. 첫 번째 수준은 프런트 엔드에서 제출하기 전이고, 두 번째 수준은 데이터가 저장되기 전, 즉 컨트롤러에서 확인이 수행되는 곳입니다. 세 번째 수준은 데이터를 저장할 때입니다. 즉, 제출된 데이터 모델이 엔터티에서 정의한 제약 조건을 준수하지 않으면 데이터를 저장할 수 없습니다. 이것이 최후의 방어선입니다. 첫 번째 수준은 주로 js 또는 jquery 프레임워크에 의존하며, 더 일반적으로 사용되는 수준은 jquery.validate.js입니다. Asp.net MVC가

검증 규칙

을 자동으로 생성할 수 있다면 여기서는 자세히 다루지 않겠습니다. 인터넷에는 많은 기사가 있습니다. 두 번째 레이어는 해당 비즈니스 로직과 관련되어 있으며 프런트 엔드에서 JavaScript를 금지하고 불법 데이터를 제출하는 것을 방지하기 위해 몇 가지 필요한 확인이 필요합니다. 여기서는 Mongoose 기반 확인의 세 번째 레이어에 대해 설명합니다. 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개 등 4개의 라우팅 규칙을 추가해야 합니다.

router.get('/book/create', homeController.bookcreateview);
router.post('/book/create', homeController.doBookCreate);
router.delete('/book/:id', homeController.delete);
router.post('/uploadImg', homeController.uploadImg);

Express 라우팅을 기반으로 Restful 라우팅을 생성할 수 있습니다. 규칙. 경로는 app_server 폴더 아래에 있습니다.

3.

controller

methodhome.bookcreateview:

module.exports.bookcreateview = function (req, res) {
    res.render('bookCreate', { title: '新增推荐图书' });
};

를 추가합니다. 이는 직접적으로 가져오는 요청이므로 직접 render를 사용하여 뷰를 렌더링합니다. 물론 이 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 부분을 만들었습니다. 코드 프로세스는 먼저 요청의 프런트 엔드에서 전달된 데이터를 얻은 다음 요청 모듈을 사용하여 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가 우리에게 반환한 확인 정보입니다.

이것은 컨트롤러의 처리 때문입니다.

  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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.