小編給大家分享一下如何開發(fā)node.js博客項目,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供龍泉驛網(wǎng)站建設、龍泉驛做網(wǎng)站、龍泉驛網(wǎng)站設計、龍泉驛網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、龍泉驛企業(yè)網(wǎng)站模板建站服務,十年龍泉驛做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
需要安裝的模塊
body-parser 解析post請求
cookies 讀寫cookie
express 搭建服務器
markdown Markdown語法解析生成器
mongoose 操作MongoDB數(shù)據(jù)庫
swig 模板解析引擎
目錄結構
db 數(shù)據(jù)庫存儲目錄
models 數(shù)據(jù)庫模型文件目錄
public 公共文件目錄(css,js,img)
routers 路由文件目錄
schemas 數(shù)據(jù)庫結構文件
views 模板視圖文件目錄
app.js 啟動文件
package.json
app.js 文件
1.創(chuàng)建應用、監(jiān)聽端口
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) 參數(shù)1:模板引擎的名稱,同時也是模板文件的后綴 參數(shù)2:表示用于解析處理模板內(nèi)容的方法
設置模板文件存放的目錄 app.set('views','./views')
注冊所使用的模板引擎 app.set('view engine','html')
3.用模板引擎去解析文件
/** * 讀取views目錄下的指定文件,解析并返回給客戶端 * 參數(shù)1:模板文件 * 參數(shù)2:給模板傳遞的參數(shù) */ res.render('index',{ title:'首頁 ', content: 'hello swig' });
4.開發(fā)過程中需要取消模板緩存的限制
swig.setDefaults({ cache: false }); app.set('view cache', false);
5.設置靜態(tài)文件托管
// 當用戶訪問的是/public路徑下的文件,那么直接返回 app.use('/public',express.static(__dirname + '/public'));
劃分模塊
前臺模塊
后臺模塊
API模塊
// 根據(jù)不同的功能劃分模塊 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 內(nèi)容頁
api模塊
/首頁
/register 用戶注冊
/login 用戶登錄
/comment 評論獲取
/comment/post 評論提交
后臺(admin)路由+模板
首頁
/ 后臺首頁
用戶管理
/user 用戶列表
分類管理
/category 分類列表
/category/add 分類添加
/category/edit 分類修改
/caterory/delete 分類刪除
文章內(nèi)容管理
/article nei內(nèi)容列表
/article/add 內(nèi)容添加
/article/edit 內(nèi)容修改
/article/delete 內(nèi)容刪除
評論內(nèi)容管理
/comment 評論列表
/comment/delete 評論刪除
功能開發(fā)順序
功能模塊開發(fā)順序
用戶
欄目
內(nèi)容
評論
編碼順序
通過Schema定義設計數(shù)據(jù)存儲結構
功能邏輯
頁面展示
連接數(shù)據(jù)庫(mongoDB)
啟動MongoDB服務端:
mongod --dbpath=G:\data\db --port=27017
啟動服務設置數(shù)據(jù)庫的存儲地址以及端口
var mongoose = require('mongoose'); // 數(shù)據(jù)庫鏈接 mongoose.connect("mongodb://localhost:27017/blog",(err) => { if(err){ console.log("數(shù)據(jù)庫連接失敗"); }else{ console.log("數(shù)據(jù)庫連接成功"); // 啟動服務器,監(jiān)聽端口 app.listen(3000,(req,res,next) => { console.log("app is running at port 3000"); }); } });
定義數(shù)據(jù)表結構和模型
對于用戶數(shù)據(jù)表(users.js)在schema文件夾下:
var mongoose = require('mongoose'); module.exports = new mongoose.Schema({ // 用戶名 username:String, // 密碼 password:String });
在models目錄下創(chuàng)建user.js模型類
var mongoose = require('mongoose'); var userSchema = require('../schemas/users'); module.exports = mongoose.model('User',userSchema);
處理用戶注冊
前端通過ajax提交用戶名和密碼
url: /api/register
后端對前端提交(POST)的數(shù)據(jù)解析
var bodyParser = require('body-parser'); // bodyParser 配置 // 通過使用這一方法,可以為req對象添加一個body屬性 app.use( bodyParser.urlencoded({extended:true})); // 在api模塊中: // 1.可以定義一個中間件,來統(tǒng)一返回格式 var responseData; router.use( function(req,res,next){ // path默認為'/',當訪問該目錄時這個中間件被調(diào)用 responseData = { code:0, message:'' }; next(); }); router.post('/register',(req,res,next) => { console.log(req.body); // 去判斷用戶名、密碼是否合法 // 判斷是否用戶名已經(jīng)被注冊 // 通過 res.json(responseData) 給客戶端返回json數(shù)據(jù) // 查詢數(shù)據(jù)庫 User.findOne({ // 返回一個promise對象 username: username }).then(function( userInfo ) { if( userInfo ){ // 數(shù)據(jù)庫中有該條記錄 ... res.json(responseData); return; } // 給數(shù)據(jù)庫中添加該條信息 var user = new User({ username:username,password:password }); return user.save(); // 返回promise對象 }).then(function( newUserInfo ){ console.log(newUserInfo); res.json(responseData); // 數(shù)據(jù)保存成功 }); });
cookies 模塊的使用
全局(app.js)注冊使用
// 設置cookie // 只要客戶端發(fā)送請求就會通過這個中間件 app.use((req, res, next) => { req.cookies = new cookies(req, res); /** * 解析用戶的cookies信息 * 查詢數(shù)據(jù)庫判斷是否為管理員 isAdmin * 注意:查詢數(shù)據(jù)庫是異步操作,next應該放在回調(diào)里邊 */ req.userInfo = {}; if (req.cookies.get("userInfo")) { try { req.userInfo = JSON.parse(req.cookies.get("userInfo")); // 查詢數(shù)據(jù)庫判斷是否為管理員 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循環(huán)
// 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 %} //重寫某一區(qū)塊
6.autoescape 自動編碼
當想在某個div中顯示后端生成的HTML代碼,模板渲染時會自動編碼,
以字符串的形式顯示。通過以下方式,可以避免這個情況:
<div id="article-content" class="content"> {% autoescape false %} {{ data.article_content_html }} {% endautoescape %} </div>
用戶管理和分頁
CRUD用戶數(shù)據(jù)
const User = require('../models/user'); // 查詢所有的用戶數(shù)據(jù) User.find().then(function(users){ }); // 根據(jù)某一字段查詢數(shù)據(jù) User.findOne({ username:username }).then(function(result){ }); // 根據(jù)用戶ID查詢數(shù)據(jù) User.findById(id).then(function(user){ }); // 根據(jù)ID刪除數(shù)據(jù) User.remove({ _id: id }).then(function(){ }); // 修改數(shù)據(jù) User.update({ _id: id },{ username: name }).then(function(){ });
數(shù)據(jù)分頁管理
兩個重要方法
limit(Number): 限制獲取的數(shù)據(jù)條數(shù)
skip(Number): 忽略數(shù)據(jù)的條數(shù) 前number條
忽略條數(shù):(當前頁 - 1) * 每頁顯示的條數(shù)
// 接收傳過來的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; // 每頁顯示的條數(shù) var skip = (cur_page - 1) * limit; //忽略的條數(shù) 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({ // 關聯(lián)字段 - 分類的id category:{ // 類型 type:mongoose.Schema.Types.ObjectId, // 引用 ref:'Category' }, // 內(nèi)容標題 title: String, // 簡介 description:{ type: String, default: '' }, // 內(nèi)容 content:{ type:String, default:'' } }); // 文章查詢時關聯(lián)category字段 Content.find().populate('category').then(contents => { // 那么通過這樣的方式,我們就可以找到Content表中的 // 關聯(lián)信息 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語法解析內(nèi)容預覽 $('#bjw-content').on('keyup blur', function () { $('#bjw-previous').html(marked($('#bjw-content').val())); });
node環(huán)境中使用
// 在模板頁面引入默認樣式 <!--語法高亮--> <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; } }); // 對內(nèi)容進行markdown語法轉(zhuǎn)換 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'); // 當用戶注冊時,根據(jù)用戶的用戶名生成隨機頭像 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表單提交一些代碼的時候,會出現(xiàn)瀏覽器攔截的現(xiàn)象,原因是:瀏覽器誤以為客戶進行xss攻擊。所以呢解決這個問題也很簡單,就是對提交的內(nèi)容進行base64或者其他形式的編碼,在服務器端進行解碼,即可解決。
以上是“如何開發(fā)node.js博客項目”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
當前標題:如何開發(fā)node.js博客項目
網(wǎng)頁URL:http://www.rwnh.cn/article40/ippiho.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導航、外貿(mào)網(wǎng)站建設、靜態(tài)網(wǎng)站、手機網(wǎng)站建設、網(wǎng)頁設計公司、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)