用Nodejs完成自己的个人博客

作者: 简心豆 | 来源:发表于2017-06-03 14:08 被阅读515次

    开始这个个人小项目已经有一段时间了,一直断断续续的,直到今天总算是初见雏形,所以就很想和大家分享一下实现的过程。首先这个的初衷就是学习nodejs,看了几天的书,自己就照着书上的代码来敲,可是由于自己安装的node是最新版,然而书比较旧,好多都不能正确运行,我想了解node的都知道它几乎每天都在更新,出现这样的情况也是必然的。所以想了下,还是在github上找个别人的项目拿来练练手,看一下项目是如何搭建的,经过仔细的琢磨总算是慢慢搭起来了。下来讲一下自己是如何实现的。


    一. 项目所用到的技术

    express框架:

    (1)可以设置中间件来响应 HTTP 请求;
    (2)定义路由表用于执行不同的 HTTP 请求动作;

    ejs模板

    用过Java的jsp的就知道,这和jsp的作用完全相同,动态生成html元素。

    mongodb数据库

    这和熟悉的mysql数据库不同,mysql是关系型数据库,没一个表的每一项时一条记录,而mongodb是集合类型的,每个集合里存储的是对象,想象一下json,就明白mongodb里存储的数据类型。

    mongoose数据库操作

    这个是针对mongodb的数据库驱动,里面封装了对数据库的各种基本操作。

    二. 项目目录

    这里写图片描述

    下面介绍下,每个目录都是干什么的:
    (1)node_modules:存放各种node插件和express框架;
    (2)schemas:在这个文件里用mongoose封装的对象来指定,数据库里要存储的数据结构。
    如下,这是一个user的数据集合里面存储的数据项的结构:

    
    > schemas/user.js
    
    var Schema = require('mongoose').Schema;
    
    var userSchema = new Schema({
        name: String,
        password: String,
        icon: String,
        sex: String,
        tel: String,
        qq: String,
        weixin: String,
        weibo: String,
        email: String
    });
    
    module.exports = userSchema;
    

    (3)models:此文件夹下的每一个js文件都映射一个对应的schemas里的文件,然后将类型暴露出去,就可以让外界进行各种数据库操做了。

    > models/user.js
    
    var mongoose = require('mongoose');
    var User = require('../schemas/user');
    
    module.exports = mongoose.model('User', User);
    

    (3)routes:看见名字就知道这个里面是对路由的各种操作,相当于Java里面的servlet要做的事情,进行页面的跳转和数据的传送。下面看routes的目录:


    这里写图片描述

    在这个文件夹下,index.js是最重要的,里面是所有路由的接口,其他的都是每个路由跳转所要执行的操作。下面的代码是index.js里的部分内容:

    
    > routes/index.js
    
    var login = require('./login');
    var blog = require('./blog');
    module.exports = function (app){
        app.get('/bloglist', blog.getAllBlog);  //跳到文章列表页
        
        app.get('/home', function (req, res){  //跳到首页
            res.render('index', {
                title: '小静博客——首页',
            });
        });
    };
    
    app.post('/doLogin', login.checkLogin); //验证登录信息
    

    可以看到我们传入了app参数,这个是express实例化的对象,所有http的get和post请求都是用app对象来完成的。
    (4)static:里面存放的是所有静态资源,比如js,css还有图片等文件。
    (5)views:里面存的是所有的html页面。
    (6)app.js:这个无疑是express框架中最重要的了,是等个项目的入口文件,在这个项目中只有该文件的生命周期是直到关闭服务器,所以可见它的重要性。在这个文件中需要引入所要使用的:

    • 各种中间件:用于设置session和cookie的express-session和cookie-parser,还有body-parser,用于处理
      JSON和application/x-www-form-urlencoded 编码的数据。
    • 驱动程序包:mongodb的驱动包mongoose;
    • 页面的模板引擎:ejs;

    连接并启动数据库,监听端口等都在这个入口文件中。如下代码所示:

    
    > app.js
    
    var express = require('express');
    var ejs = require('ejs');
    var bodyParser = require('body-parser');
    var session = require('express-session');
    var cookieParser = require('cookie-parser');
    var mongoose = require('mongoose');
    
    //将路由文件引入
    var route = require('./routes/index');
    
    //设置端口
    var port = process.env.PORT || 3000;
    
    var app = express();
    
    //设置试图的根目录
    app.set('views', './views/pages');
    
    //设置试图的模板引擎
    app.engine('.html', ejs.__express);
    app.set('view engine', 'html'); 
    
    //设置静态资源路径
    app.use(express.static('./static'));  
    
    // 解析 application/x-www-form-urlencoded 
    app.use(bodyParser.urlencoded({ extended: false })); 
    // 解析 application/json 
    app.use(bodyParser.json()); 
    
    //设置session和cookie
    app.use(cookieParser());
    app.use(session({
    secret: '12345',
        name: 'testapp',
        resave: false,
        saveUninitialized: true,
    }));
    
    //监听端口 
    app.listen(port);
    
    console.log("Server is runnng on " + port);
    
    //连接mongodb数据库
    mongoose.Promise = global.Promise;  //不加这句会报错
    mongoose.connect('mongodb://127.0.0.1/myblog'); 
    mongoose.connection.on('open', function (){
        console.log('Connected to Mongoose');
    });
    
    route(app);  //初始化所有路由
    
    

    三. 项目的难点

    写这个项目最大的感受就是,node是异步的,和之前一直使用的java有很大区别,很容易出错,可是node页提供了很强大的机制,Promise,他让所有的异步操作看起来更像是顺序的,也让代码变得可读性更强了。下面是获得某条博客信息的具体代码,来看看Promise的魅力:

    //获得某条博客的信息,并更新浏览次数
    exports.getBlog = function (req, res){
        var blogid = req.params.id;
        var error = '';
        var user = req.session.user || null;
        Blog.findOne({_id: blogid}, function (err, blog){
            if (blog == null){
                error = '该文章被主人删除!';
                res.render({
                    error: error
                });
            }else{
    
                //更新文章阅读次数
                var promise1 = updateLook_num(blogid);
                //查找文章作者的信息
                var promise2 = findUser(blog.authorid);
                //查找该博客的所有评论信息
                var promise3 = findReview(blogid);
                //查看未读消息总数
                var promise4 = message.totalUnreadMess(blog.authorid);
    
                Promise.all([promise1, promise2, promise3, promise4]).then(function (result){
                    res.render('blogdetail', {
                        title: blog.title,
                        error: error,
                        blog: blog,
                        user: user,
                        author: result[1],
                        reviewlist: result[2],
                        totalmess: result[3],
                    }); 
                }).catch(function (err){
                    console.log(err);
                });
            }   
        });
    }
    

    上面的每个promise对象都代表了一个异步操作,如果不适用Promise就会陷入代码嵌套的无底洞,那将会是灾难,可以有了Promise将每个异步操作都分开书写,然后在用all方法去执行,代码就很容易理解,可读性和可维护性都会大大提高。

    四. 截图
    附上自己的最终截图吧:

    博客列表页


    这里写图片描述

    文章详情页

    这里写图片描述 这里写图片描述

    评论消息提醒页

    这里写图片描述

    在这篇博客中,我并没有多说代码如何编写,而是主要说了项目的架构,我想对大多数人来说明白项目的架构,就会有个整体的概念,心里就会有个模板,至于代码的具体实现就看自己的js功底了。

    代码已上传至github:https://github.com/lwjcode/myblog
    欢迎fork and star.

    相关文章

      网友评论

      本文标题:用Nodejs完成自己的个人博客

      本文链接:https://www.haomeiwen.com/subject/crtmfxtx.html