使用工具:webstorm
数据库:mongoose
node.js web应用框架:Express
前端框架:JQuery、Bootstrap
1、下载安装node之后,新建文件(这里取名blog),初始化项目,在控制台输入指令:npm init,从而生成了package.json
2、下载第三方模块和中间件(指令:npm install -g 包名)
express
body-parser:HTTP请求体解析的中间件
Cookies
markdown:语法解析生成模块
mongoose:后续的数据库操作将会使用到
swig:渲染模板解析引擎
3、新建文件:
app.js
db:用于数据库存储目录
public:用于存放公共文件目录(如css、js、image)
schemas:数据库结构文件目录
models:数据库模型文件目录
routers:路由
views:模板视图文件目录
node_modules:第三方模板目录
4、配置app.js
express:
//加载express模块
var express=require('express');
//创建app应用=>NodeJS Http.createServer();
var app=express();
//设置静态文件托管
//当用户访问的URL以/public开始,那么直接返回对应__dirname+'/public'下的文件
app.use('/public',express.static(__dirname + '/public'));
mongoose:
mongoose的connect方法,第一个参数是连接数据库的地址(mongodb://localhost:27018/blog),监听的端口是8082;
//加载数据库模块
var mongoose=require('mongoose');
mongoose.connect('mongodb://localhost:27018/blog',{useNewUrlParser:true, useUnifiedTopology: true},function(err){
if(err){
console.log("fail!");
}else{
console.log("success!");
app.listen(8082);
}
});
body-parse:
bodyParser.urlencoded(),解析文本格式,这个方法默认使用UTF-8编码,解析后,其后的所有的req.body中将会是一个键值对对象;extend:默认为true。设置为true时,会使用qs库解析URL编码的数据。设置为false时,会使用querystring库解析URL编码的数据;
var bodyParser=require('body-parser');
//bodyParser设置
app.use(bodyParser.urlencoded({extended:true}));
cookies:这里是处理保存用户的登录状态
其中需要在api.js用户登录接口里发送一个cookies信息,浏览器将保存cookies信息;
//保存cookies信息
req.cookies.set('userInfo',JSON.stringify({
id:userInfo._id,
username:userInfo.username,
}));
app.js:
var Cookies=require('cookies');
//cookies设置
app.use(function(req,res,next){
req.cookies=new Cookies(req,res);
//解析登录用户的cookies信息
req.userInfo={};
//判断是否有名为userInfo的cookies信息
if(req.cookies.get('userInfo')){
try {
req.userInfo=JSON.parse(req.cookies.get('userInfo'));
//获取当前登录用户的类型,是否是管理员
User.findById(req.userInfo.id).then(function (userInfo) {
req.userInfo.isAdmin=Boolean(userInfo.isAdmin);
next();
});
}catch(e){
next();
}
}else{
next();
}
});
swig:
var swig=require('swig');
//配置应用模板
//定义当前应用所使用的模板引擎
//第一个参数:模板引擎的名称,同时也是模板文件的后缀,第二个参数表示用于解析处理模板内容的方法;
app.engine('html',swig.renderFile);
//设置模板文件存放的目录,第一个参数必须是views,第二个参数是目录
app.set('views','./views');
//注册所使用的模板引擎,第一个参数必须是view engine,第二个参数和app.engine这个方法中定义的模板引擎的名称(第一个参数)是一致的
app.set('view engine','html');
//在开发过程中,需要取消模板缓存
swig.setDefaults({cache:false});
分模块处理:
app.use('/admin',require('./routers/admin'));
app.use('/api',require('./routers/api'));
app.use('/',require('./routers/main'));
5、新建数据库,以及数据库存储的字段,这里以用户信息为例(文件路径:schemas/users.js):
//加载mongoose
var mongoose=require('mongoose');
//表结构
module.exports=new mongoose.Schema({
//用户名
username:String,
//密码
password:String,
//登录状态
isAdmin:{
type:Boolean,
default:false
}
});
6、创建模型,加载user.js,文件路径:models/User.js
//加载mongoose
var mongoose=require('mongoose');
//加载users
var userSchema=require("../schemas/users");
//mongoose的model方法,创建名为User的模型
module.exports=mongoose.model("User",userSchema);
7、新建路由文件,在routers下新建文件api.js;
下面新建一个路由,user路径的get请求,用res.render来渲染视图模板,在渲染视图前还做了分页处理,在分页中,如需进行排序,则可在查询数据库时多加条件sort({排序名:1:升序 , -1:降序});
var express=require('express');
var router=express.Router();
var User=require('../models/User');
router.get('/user',function(req,res,next){
/*
* 从数据库中读取所有数据
* 每页显示条数:limit
* 当前页:page
* 总页数:pages
* */
var page=Number(req.query.page||1),
limit=2,
pages=0;
User.count().then(function(count){
//计算总页数
pages=Math.ceil(count/limit);
//当前页不能超过总页数
page=Math.min(page,pages);
//当前页不能小于1
page=Math.max(page,1);
var skip=(page-1)*limit;
User.find().limit(limit).skip(skip).then(function(users){
res.render('admin/user_index',{
userInfo:req.userInfo,
users:users,
pages:pages,
limit:limit,
count:count,
page:page,
})
});
});
});
这里有一个“分类专栏”,专栏里点击某一个分类,就会筛选出有该分类的相关文章;这里的处理是传ID,然后通过ID在数据库查询,如果有ID,则显示该ID的下的分类文章,否则where为空显示全部文章;
router.get('/',function(req,res,next){
data.catalog=req.query.catalog||'';
var where={};
if(data.catalog){
where.catalog=data.catalog;
}
Content.where(where).then(function(count){
return Content.where(where).find().populate(['catalog','user']);
}).then(function(contents){
data.contents=contents;
res.render('main/index',data);
})
});
文件启动命令为:
在下载mongoose的文件夹的/bin里启动,命令:mongod --dbpath=D:/Blog/db(项目文件Blog下的db) --port=27018(数据库的端口);
我这里设置的端口是8082,访问地址是:http://localhost:8082
首页展示:
后台展示:
发表评论,这里写了一个post请求,然后提交数据保存到数据库,然后再重新加载一遍评论;
/*
* 提交评论
* */
router.post('/content/comment',function(req,res){
//获取该文章的id
var contentId=req.body.contentId||'';
//用于保存评论信息
var postId={
//用户名
username:req.userInfo.username,
//评论提交时间
postTime:new Date(),
//评论内容
content:req.body.content,
};
//查询是否有该id
Content.findOne({
_id:contentId
}).then(function(content){
//comment字段添加该评论信息并保存
content.comment.push(postId);
return content.save();
}).then(function(data){
responseData.data=data;
res.json(responseData);
})
});
文章详情页展示: