亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

node.js博客項目開發手記

2024-05-06 16:43:09
字體:
來源:轉載
供稿:網友

需要安裝的模塊

  • 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/userrouter.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();  }});// 當用戶登錄或注冊成功之后,可以為其設置cookiesreq.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) * 每頁顯示的條數

// 接收傳過來的pagelet query_page = Number(req.query.page) || 1;query_page = Math.max(query_page, 1); // 限制最小為1query_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.jsvar mongoose = require('mongoose');var contentSch = require('../schemas/contentSch');module.exports = mongoose.model('Content',contentSch);// contentSch.jsmodule.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或者其他形式的編碼,在服務器端進行解碼,即可解決。

源碼地址:https://github.com/bjw1234/blog


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久app| 亚洲精品成人免费| 国产精品视频专区| 高清日韩电视剧大全免费播放在线观看| 欧美一区二区.| 欧美另类老女人| 国产精品久久久久久久久久ktv| 尤物九九久久国产精品的分类| 久久久av电影| 久久中文字幕在线视频| 久色乳综合思思在线视频| 国产精品午夜视频| 国产欧亚日韩视频| 成人黄色在线免费| 国产精品美女久久久久久免费| 国产精品中文字幕在线观看| 久久成人精品电影| 亚洲色在线视频| 欧美视频裸体精品| 久久精品国产亚洲一区二区| 国产精品久久久久影院日本| 欧美激情videos| 欧美日韩国产二区| 91精品啪在线观看麻豆免费| 国产乱肥老妇国产一区二| 欧美精品九九久久| 亚洲一区二区三区视频播放| 亚洲天堂免费观看| 国产精品高潮粉嫩av| 国产精品91久久久久久| 亚洲国产精品va在线看黑人| 成人444kkkk在线观看| 亚洲精品在线视频| 97免费视频在线播放| 国产69精品久久久久9| 国产日韩在线播放| 亚洲大胆人体视频| 亚洲最新av网址| 国产成+人+综合+亚洲欧洲| 日韩视频亚洲视频| 欧美国产乱视频| 欧美午夜精品伦理| 欧美一级黑人aaaaaaa做受| 久久久人成影片一区二区三区| 日韩久久精品电影| 亚洲精品之草原avav久久| 国产精品xxx视频| 国产在线不卡精品| 97人洗澡人人免费公开视频碰碰碰| 欧美成人亚洲成人| 成人久久久久爱| 亚洲色图25p| 亚洲精品中文字幕有码专区| 最近2019年手机中文字幕| 亚洲美女视频网站| 欧美日韩另类在线| 国产精品99久久久久久白浆小说| 久久久久久久91| 亚洲第一精品夜夜躁人人爽| 亚洲精品视频网上网址在线观看| 亚洲第一区在线观看| 日韩美女视频免费看| 久久久久亚洲精品国产| 国产精品入口夜色视频大尺度| 91探花福利精品国产自产在线| 欧美性xxxx极品高清hd直播| 久久国产精品99国产精| 国产精品入口尤物| 亚洲色图五月天| 亚洲国产精品一区二区久| 伦伦影院午夜日韩欧美限制| 亚洲高清一二三区| 精品二区三区线观看| 国产精品一区二区3区| 日韩性xxxx爱| 欧美日韩美女在线观看| 美女国内精品自产拍在线播放| 欧美中文字幕精品| 欧美裸体男粗大视频在线观看| 黄色成人在线播放| 日本91av在线播放| 在线视频亚洲欧美| 亚洲综合中文字幕68页| 久久精品国亚洲| 欧美一级淫片丝袜脚交| 成人免费黄色网| 国产一区红桃视频| 欧美精品性视频| 久久伊人91精品综合网站| 日韩亚洲国产中文字幕| 美女扒开尿口让男人操亚洲视频网站| 亚洲天堂av高清| 亚洲成人av片在线观看| 日韩电影中文字幕在线| 欧美日韩一区二区免费视频| 国产日韩亚洲欧美| 精品久久久香蕉免费精品视频| 欧美日韩精品在线| 国产免费一区视频观看免费| 国a精品视频大全| 亚洲第一中文字幕| 欧美精品videossex88| 日韩av三级在线观看| 国产亚洲精品美女久久久| 日韩在线免费观看视频| 亚洲一区二区在线| 成人黄色免费网站在线观看| 久久久久久久久久久av| 国产国语刺激对白av不卡| 国产日韩精品入口| 大胆欧美人体视频| 欧美成人性生活| 亚洲新中文字幕| 久久精品成人一区二区三区| 91在线精品播放| 国产又爽又黄的激情精品视频| 北条麻妃一区二区三区中文字幕| 91国产一区在线| 亚洲人成网站777色婷婷| 久久久国产视频| 亚洲美女www午夜| 久久青草福利网站| 国产成人亚洲综合91| 久久九九有精品国产23| 亚洲第一二三四五区| 国产精品自产拍在线观看中文| 欧美高清在线观看| 久久91精品国产91久久久| 久久成人av网站| 亚洲成人激情视频| 中文字幕精品在线| 日韩精品免费在线视频观看| 成人美女免费网站视频| 久久av在线看| 国产不卡视频在线| 欧美性xxxxxxx| 国产日韩欧美日韩大片| 欧美国产日本高清在线| 久久久久久这里只有精品| 亚洲美女黄色片| 国产亚洲精品美女久久久久| 中文字幕精品av| 久久精品这里热有精品| 国产999精品| 日韩中文字幕在线| 国产+成+人+亚洲欧洲| 俺也去精品视频在线观看| 国产999精品久久久影片官网| 91在线观看免费高清完整版在线观看| 久久久综合av| 国产精品成人av性教育| 2019亚洲男人天堂| 国产一区二区三区在线观看视频| 这里只有精品丝袜| 欧美日韩国产精品一区二区三区四区| 爽爽爽爽爽爽爽成人免费观看| 欧美中文字幕第一页| 国产精品久久久久福利| 精品久久久免费| 亚洲美女视频网| 欧美主播福利视频| 亚洲人精选亚洲人成在线| 91成品人片a无限观看| 国产成人精品999|