温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何开发node.js博客项目

发布时间:2021-08-20 11:35:52 来源:亿速云 阅读:164 作者:小新 栏目:web开发

小编给大家分享一下如何开发node.js博客项目,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

需要安装的模块

  • body-parser 解析post请求

  • cookies 读写cookie

  • express 搭建服务器

  • markdown Markdown语法解析生成器

  • mongoose 操作Mongodb数据库

  • swig 模板解析引擎

目录结构

  • db 数据库存储目录

  • models 数据库模型文件目录

  • public 公共文件目录(css,js,img)

  • routers 路由文件目录

  • schemas 数据库结构文件

  • views 模板视图文件目录

  • app.js 启动文件

  • package.json

app.js 文件

1.创建应用、监听端口

const app = express(); app.get('/',(req,res,next) => {   res.send("Hello World !"); }); app.listen(3000,(req,res,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.用模板引擎去解析文件

/**  * 读取views目录下的指定文件,解析并返回给客户端   * 参数1:模板文件  * 参数2:给模板传递的参数   */   res.render('index',{   title:'首页 ',   content: 'hello swig' });

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

swig.setDefaults({  cache: false }); app.set('view cache', false);

5.设置静态文件托管

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

划分模块

  • 前台模块

  • 后台模块

  • API模块

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

对于管理员模块 admin.js

var express = require('express'); var router = express.Router(); // 比如访问 /admin/user router.get('/user',function(req,res,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

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

var mongoose = require('mongoose'); // 数据库链接 mongoose.connect("mongodb://localhost:27017/blog",(err) => {   if(err){     console.log("数据库连接失败");   }else{     console.log("数据库连接成功");    // 启动服务器,监听端口     app.listen(3000,(req,res,next) => {       console.log("app is running at port 3000");     });   } });

定义数据表结构和模型

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

var mongoose = require('mongoose'); module.exports = new mongoose.Schema({   // 用户名   username:String,   // 密码   password:String });

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

var mongoose = require('mongoose'); var userSchema = require('../schemas/users'); module.exports = mongoose.model('User',userSchema);

处理用户注册

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

url: /api/register

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

var bodyParser = require('body-parser'); // bodyParser 配置 // 通过使用这一方法,可以为req对象添加一个body属性 app.use( bodyParser.urlencoded({extended:true})); // 在api模块中: // 1.可以定义一个中间件,来统一返回格式 var responseData; router.use( function(req,res,next){ // path默认为'/',当访问该目录时这个中间件被调用   responseData = {      code:0,     message:''   };   next(); }); router.post('/register',(req,res,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)注册使用

// 设置cookie // 只要客户端发送请求就会通过这个中间件 app.use((req, res, next) => {   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 % }

<p>{ { key } } -- { { val } }</p>

{ % endfor % }

5.set命令

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

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

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

6.autoescape 自动编码

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

<div id="article-content" class="content">   {% autoescape false %}   {{ data.article_content_html }}   {% endautoescape %} </div>

用户管理和分页

CRUD用户数据

const User = require('../models/user'); // 查询所有的用户数据 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) * 每页显示的条数

// 接收传过来的page let query_page = Number(req.query.page) || 1; query_page = Math.max(query_page, 1); // 限制最小为1 query_page = Math.min(Math.ceil(count / limit), query_page); // 限制最大值 count/limit向上取整 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 传给页面 });

文章的表结构

// 对于content.js var mongoose = require('mongoose'); var contentSch = require('../schemas/contentSch'); 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中直接使用

<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"> <script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script> <script src="https://cdn.bootcss.com/marked/0.3.17/marked.min.js"></script> // 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环境中使用

// 在模板页面引入默认样式 <!--语法高亮--> <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"> const marked = require('marked'); const hljs = require('highlight.js'); // 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语法转换 data.article_content_html = marked(article.content);

使文本域支持Tab缩进

$('#bjw-content').on('keydown',function(e){   if(e.keyCode === 9){ // Tab键      var position = this.selectionStart + 2; // Tab === 俩空格     this.value = this.value.substr(0,this.selectionStart) + " " + this.value.substr(this.selectionStart);     this.selectionStart = position;     this.selectionEnd = position;     this.focus();     e.preventDefault();   } });

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();     }   }); });

随机用户头像生成

// 引入对应的库 const crypto = require('crypto'); const identicon = require('identicon.js'); // 当用户注册时,根据用户的用户名生成随机头像 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博客项目”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI