热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用Nodejs完成自己的个人博客

开始这个个人小项目已经有一段时间了,一直断断续续的,直到今天总算是初见雏形,所以就很想和大家分享一下实现的过程。首先这个的初衷就是学习nodejs,看了几天的书,自己就照着书上的代码来敲,可是由

开始这个个人小项目已经有一段时间了,一直断断续续的,直到今天总算是初见雏形,所以就很想和大家分享一下实现的过程。首先这个的初衷就是学习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.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/SpiritLiftedHigh/myblog
欢迎fork and star.


推荐阅读
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
  • Allegro总结:1.防焊层(SolderMask):又称绿油层,PCB非布线层,用于制成丝网印板,将不需要焊接的地方涂上防焊剂.在防焊层上预留的焊盘大小要比实际的焊盘大一些,其差值一般 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • 本文介绍了一些Java开发项目管理工具及其配置教程,包括团队协同工具worktil,版本管理工具GitLab,自动化构建工具Jenkins,项目管理工具Maven和Maven私服Nexus,以及Mybatis的安装和代码自动生成工具。提供了相关链接供读者参考。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • Yii framwork 应用小窍门
    Yiiframework应用小窍门1.YiiFramework]如何获取当前controller的名称?下面语句就可以获取当前控制器的名称了!Php代码 ... [详细]
author-avatar
手机用户2602926865
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有