node.js博客项目开发手记

前端之家收集整理的这篇文章主要介绍了node.js博客项目开发手记前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

需要安装的模块

  • body-parser 解析post请求
  • cookies 读写cookie
  • express 搭建服务器
  • markdown Markdown语法解析生成
  • mongoose 操作Mongodb数据库
  • swig 模板解析引擎

目录结构

app.js 文件

1.创建应用、监听端口

app.get('/',(req,res,next) => {
res.send("Hello World !");
});
app.listen(3000,next) => {
console.log("app is running at port 3000");
});

2.配置应用模板

  • 定义使用的模板引擎 app.engine('html',swig.renderFile) 参数1:模板引擎的名称,同时也是模板文件的后缀 参数2:表示用于解析处理模板内容方法
  • 设置模板文件存放的目录 app.set('views','./views')
  • 注册所使用的模板引擎 app.set('view engine','html')

3.用模板引擎去解析文件

文件,解析并返回给客户端 * 参数1:模板文件 * 参数2:给模板传递的参数 */

res.render('index',{
title:'首页 ',content: 'hello swig'
});

4.开发过程中需要取消模板缓存的限制

5.设置静态文件托管

用户访问的是/public路径下的文件,那么直接返回 app.use('/public',express.static(__dirname + '/public'));

划分模块

功能划分模块 app.use('/',require('./routers/main')); app.use('/admin',require('./routers/admin')); app.use('/api',require('./routers/api'));

对于管理员模块 admin.js

// 比如访问 /admin/user
router.get('/user',function(req,next) {
res.send('User');
});
module.exports = router;

前台路由 + 模板

main 模块 / 首页 /view 内容

api模块

/首页 /register 用户注册 /login 用户登录 /comment 评论获取 /comment/post 评论提交

后台(admin)路由+模板

首页

/ 后台首页

用户管理

/user 用户列表

分类管理

/category 分类列表 /category/add 分类添加 /category/edit 分类修改 /caterory/delete 分类删除

文章内容管理

/article nei内容列表 /article/add 内容添加 /article/edit 内容修改 /article/delete 内容删除

评论内容管理

/comment 评论列表 /comment/delete 评论删除

功能开发顺序

功能模块开发顺序

编码顺序

  • 通过Schema定义设计数据存储结构
  • 功能逻辑
  • 页面展示

连接数据库(mongoDB)

启动MongoDB服务端:

mongod --dbpath=G:\data\db --port=27017

启动服务设置数据库的存储地址以及端口

{ if(err){ console.log("数据库连接失败"); }else{ console.log("数据库连接成功"); // 启动服务器,监听端口 app.listen(3000,next) => { console.log("app is running at port 3000"); }); } });

定义数据表结构和模型

对于用户数据表(users.js)在schema文件夹下:

用户名 username:String,// 密码 password:String });

在models目录下创建user.js模型类

处理用户注册

前端通过ajax提交用户名和密码

url: /api/register

后端对前端提交(POST)的数据解析

// 在api模块中:
// 1.可以定义一个中间件,来统一返回格式
var responseData;
router.use( function(req,next){ // path默认为'/',当访问该目录时这个中间件被调用
responseData = {
code:0,message:''
};
next();
});

router.post('/register',next) => {
console.log(req.body);
// 去判断用户名、密码是否合法
// 判断是否用户名已经被注册
// 通过 res.json(responseData) 给客户端返回json数据

// 查询数据库
User.findOne({ // 返回一个promise对象
username: username
}).then(function( userInfo ) {
if( userInfo ){ // 数据库中有该条记录
...
res.json(responseData);
return;
}
// 给数据库添加该条信息
var user = new User({ username:username,password:password });
return user.save(); // 返回promise对象
}).then(function( newUserInfo ){
console.log(newUserInfo);
res.json(responseData); // 数据保存成功
});
});

cookies 模块的使用

全局(app.js)注册使用

{ req.cookies = new cookies(req,res);

/**

  • 解析用户的cookies信息
  • 查询数据库判断是否为管理员 isAdmin
  • 注意:查询数据库是异步操作,next应该放在回调里边
    */
    req.userInfo = {};
    if (req.cookies.get("userInfo")) {
    try {
    req.userInfo = JSON.parse(req.cookies.get("userInfo"));
    // 查询数据库判断是否为管理员
    User.findById(req.userInfo._id).then(function (result) {
    req.userInfo.isAdmin = Boolean(result.isAdmin);
    next();
    });
    } catch (e) {
    next();
    }
    } else {
    next();
    }
    });

// 当用户登录注册成功之后,可以为其设置cookies
req.cookies.set("userInfo",JSON.stringify({
_id:result._id,username:result.username
}));

swig模板引擎

1.变量

{{ name }}

2.属性

{{ student.name }}

3.if判断

{ % if name === '郭靖' % }

hello 靖哥哥

{ % endif % }

4.for循环

// arr = [1,2,3]

{ % for key,val in arr % }

{ { key } } -- { { val } }

{ % endfor % }

5.set命令

用来设置一个变量,在当前上下文中复用

{% set foo = [0,1,3,4,5] %}

{% extends 'layout.html' %} // 继承某一个HTML模板 {% include 'page.html' %} // 包含一个模板到当前位置 {% block main %} xxx {% endblock %} //重写某一区块

6.autoescape 自动编码

当想在某个div中显示后端生成HTML代码,模板渲染时会自动编码, 以字符串的形式显示。通过以下方式,可以避免这个情况:

用户管理和分页

CRUD用户数据

// 查询所有的用户数据
User.find().then(function(users){

});

// 根据某一字段查询数据
User.findOne({
username:username
}).then(function(result){

});

// 根据用户ID查询数据
User.findById(id).then(function(user){

});

// 根据ID删除数据
User.remove({
_id: id
}).then(function(){

});

// 修改数据
User.update({
_id: id
},{
username: name
}).then(function(){
});

数据分页管理

两个重要方法

limit(Number): 限制获取的数据条数

skip(Number): 忽略数据的条数 前number条

忽略条数:(当前页 - 1) * 每页显示的条数

var cur_page = query_page; // 当前页
var limit = 10; // 每页显示的条数
var skip = (cur_page - 1) * limit; //忽略的条数

User.find().limit(limit).skip(skip).then(function(users){
...
// 将当前页 page 传给页面
// 将最大页码 maxPage 传给页面
});

文章的表结构

module.exports = mongoose.model('Content',contentSch);

// contentSch.js
module.exports = new mongoose.Schema({

// 关联字段 - 分类的id
category:{
// 类型
type:mongoose.Schema.Types.ObjectId,// 引用
ref:'Category'
},// 内容标题
title: String,// 简介
description:{
type: String,default: ''
},// 内容
content:{
type:String,default:''
}
});

// 文章查询时关联category字段
Content.find().populate('category').then(contents => {
// 那么通过这样的方式,我们就可以找到Content表中的
// 关联信息 content.category.category_name
});

MarkDown语法高亮

在HTML中直接使用

<script src="https://cdn.bootcss.com/marked/0.3.17/marked.min.js"&gt;

// marked相关配置
marked.setOptions({
renderer: new marked.Renderer(),gfm: true,tables: true,breaks: false,pedantic: false,sanitize: true,smartLists: true,smartypants: false,highlight: function (code) {
return hljs.highlightAuto(code).value;
}
});

// MarkDown语法解析内容预览
$('#bjw-content').on('keyup blur',function () {
$('#bjw-prevIoUs').html(marked($('#bjw-content').val()));
});

node环境中使用

页面引入默认样式 const marked = require('marked');
const hljs = require('highlight.js');

// marked相关配置
marked.setOptions({
renderer: new marked.Renderer(),highlight: function (code) {
return hljs.highlightAuto(code).value;
}
});

// 对内容进行markdown语法转换
data.article_content_html = marked(article.content);

使文本域支持Tab缩进

layer 弹框

显示弹框 function showDialog(text,icon,callback) { layer.open({ time: 1500,anim: 4,offset: 't',icon: icon,content: text,btn: false,title: false,closeBtn: 0,end: function () { callback && callback(); } }); });

随机用户头像生成

// 当用户注册时,根据用户用户名生成随机头像
let hash = crypto.createHash('md5');
hash.update(username);
let imgData = new identicon(hash.digest('hex').toString());
let imgUrl = 'data:/image/png;base64,'+imgData;

orm表单提交的小问题

当使用form表单提交一些代码的时候,会出现浏览器拦截的现象,原因是:浏览器误以为客户进行xss攻击。所以呢解决这个问题也很简单,就是对提交的内容进行base64或者其他形式的编码,在服务器端进行解码,即可解决

源码地址:

猜你在找的Node.js相关文章