Node.js + Express + MongoDB實現(xiàn)簡易的CRUD

Express是一個極簡的Node.js Web框架。Express官網(wǎng)

學習了express之后玄妈,簡單實現(xiàn)了一個CRUD demo,整理了一些核心點和第三方中間件的使用髓梅。

  1. 引入express拟蜻,啟動一個服務
const express = require('express');

const app = express();

app.listen(3000, () => {
    console.log('runing...')
})
  1. 托管靜態(tài)文件

對于諸如image、css枯饿、js等靜態(tài)資源酝锅,Express內置了一個 express.static 中間件函數(shù)。

express.static(root, options);
/**
 *  1. 參數(shù)1:靜態(tài)文件根目錄
 *  2. 參數(shù)2:可選配置項 具體參考 http://www.expressjs.com.cn/4x/api.html#express.static
 * /

比如通過這行代碼就可以訪問static目錄下的靜態(tài)文件

app.use(express.static('static'));
http://127.0.0.1:3000/image/dog.png
http://127.0.0.1:3000/css/common.css
...

如果使用多個靜態(tài)資源目錄奢方,則多次調用即可搔扁。

如果為express.static函數(shù)所托管的文件創(chuàng)建虛擬路徑前綴(這個路徑前綴實際上在文件系統(tǒng)中不存在),請指定靜態(tài)目錄的掛載路徑蟋字,如下:

app.use('/static', express.static('static'))

就可以通過帶有static前綴的路徑來訪問static靜態(tài)目錄中的資源了稿蹲。如:

http://127.0.0.1:3000/static/image/dog.png
http://127.0.0.1:3000/static/css/common.css
...
  1. 路由的使用
app.METHOD(path, callback);

如:

app.get('/', (req, res) => {})

app.post('/user', (req, res) => {})

實際開發(fā)中不會把路由全部掛載在app上,不但不易于維護鹊奖,而且違背了模塊化開發(fā)的思想苛聘。Express提供了一個Router函數(shù),用于創(chuàng)建路由實例(容器),作為一個中間件函數(shù)设哗,掛載到app上唱捣。

// 創(chuàng)建路由容器
const router = express.Router();

roouter.get('/', (req, res) => {})
router.post('/user', (req, res) => {})
// 亦可以鏈式調用

app.use(router)
  1. body-parser第三方庫用于獲取客戶端post提交的數(shù)據(jù)

    npm i body-parser
    
    • 配置
    const bodyParser = require('body-parser');
    
    // body-parser配置
    // parse application/x-www-form-urlencoded
    app.use(bodyParser.urlencoded({ extended: false }))
    // parse application/json
    app.use(bodyParser.json())
    
    • 獲取post提交的數(shù)據(jù)
    req.body
    
  2. 模板引擎使用art-template

    • 安裝
    npm install --save art-template
    npm install --save express-art-template
    
    • 配置
    // 模板引擎配置 默認去views目錄下查找
    
    app.engine('html', require('express-art-template')); // 參數(shù)1:模板的后綴
    
    app.set('view options', {
        debug: process.env.NODE_ENV !== 'production'
    });
    
    • 使用
    res.render(view [, locals] [, callback])
    /* 1. view 模板名
    *  2. 模板需要的數(shù)據(jù)
    *  3. 回調,兩個參數(shù)网梢, err 和 html(渲染好的字符串)
    * /
    

    例:

    router.get('/user', (req, res) => {
         res.render('index.html', {
             userInfo: {
                 name: 'Jack',
                 age: 12
            }
        }, (err, html) => {
            if (err) thorw err;
        })
    })
    
  3. md5加密
    使用md5對用戶注冊和登錄的密碼進行加密

    npm i md5
    
    const md5 = require('md5');
    
    // 采用二次加密震缭,生產(chǎn)中一般會在第一次加密后拼接sign以提高安全性
    password = md5(md5(password) + 'userManage');
    
  4. 保存登錄和注冊狀態(tài)
    用戶注冊和登錄后均跳轉到首頁,并保存登錄狀態(tài)澎粟,使用 express-session是針對express的一個中間件

    npm i express-session
    
    • session 配置
    app.use(session({
        // 配置加密字符串蛀序,會在原有加密的基礎上欢瞪,拼接起來再次加密活烙;目的是防止客戶端惡意篡改,提高安全性
        secret: 'keyboard cat',
        resave: false,
    
        // 無論是否需要 session遣鼓,默認給客戶端分配session啸盏,如果設置成false,只有服務端設置了session的時候才會給客戶端分配session
        saveUninitialized: true,
        cookie: {
            // 設置cookie的過期時間
            maxAge: 1000 * 10
        }
    }))
    

    通過req.session.xxx來獲取設設置session;

    注意:

    session默認存儲在內存骑祟,服務器一旦重啟就會丟失回懦,真正在生產(chǎn)環(huán)境session采用持久化存儲。

    • 清除session:
    req.session.XXX = null;
    
  5. 統(tǒng)一處理404和500
    處理404的中間件在 app.use(router) 之后次企,因為只有router上掛載的所有路由都匹配不到的時候才會執(zhí)行404中間件怯晕。

    app.use((req, res) => {
        res.render('error/404.html')
    })
    

    基本上每個接口都會考慮500的情況,而且每次的處理邏輯都是一樣的缸棵,所以通過中間件統(tǒng)一處理舟茶。全局處理錯誤中間件,在需要的地方調用 next() 傳入 err 對象堵第,則會默認查找具有四個參數(shù)的中間件吧凉,并執(zhí)行相應的回調

    app.use((err, req, res, next) => {
        res.status(500).json({
            code: 500,
            msg: err.msg
        })
    })
    
  6. 數(shù)據(jù)庫
    數(shù)據(jù)庫使用第三方庫 mongoose

    npm i mongoose
    

    使用:

    • 加載模塊
    const mongoose = require('mongoose');
    
    
    • 連接數(shù)據(jù)庫
      沒有userManage 數(shù)據(jù)庫的話會自動創(chuàng)建,并且如果沒有數(shù)據(jù) 執(zhí)行show dbs的時候不會顯示該數(shù)據(jù)庫踏志,當有了數(shù)據(jù)后就會顯示
    mongoose.connect('mongodb://localhost/userManage');
    
    • 設計表結構

    MongoDB 是動態(tài)的阀捅,通過代碼來設計數(shù)據(jù)庫表結構,靈活性還是很強的

    const UserManageSchema = new Schema({
        userName: {
            type: String,
            required: true,
            default: ''
        },
        age: {
            type: Number,
            required: true
        },
        gender: {
            type: Number,
            required: true,
            enum: [0, 1]
        },
        birthday: {
            type: String
        },
        job: {
            type: String
        },
        describe: {
            type: String
        }
    })
    
    • 創(chuàng)建構造器模型 即集合

    比如: 創(chuàng)建用戶表

    const UserManage = mongoose.model('userManage', UserManageSchema);
    // 參數(shù)1 為集合名针余,會轉換成小寫復數(shù)的形式饲鄙,即usermanages MangOOSE自動尋找模型名稱的復數(shù)版本 
    // 參數(shù)2為集合的架構
    
    • 新增數(shù)據(jù)
      新增數(shù)據(jù)需要創(chuàng)建集合的實例,傳入要新增的數(shù)據(jù)對象圆雁,調用save方法忍级。
    new UserManage(DATA).save((err, data) => {}) // data為插入后的數(shù)據(jù),帶數(shù)據(jù)庫生成的主鍵 _id
    
    • 查摸柄、改颤练、刪通過集合直接調用對應的方法即可
      以查為例:以郵箱或者昵稱為條件
    UserManage.findOne({
        $or: [
            {email},
            {nickName}
        ]
    }, (err, data) => {
        if (err) return res.status(500).send('server error');
        return res.send(data);
    }) 
    

服務端重定向只針對同步請求,對異步請求無效。

項目demo移步這里 github

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末嗦玖,一起剝皮案震驚了整個濱河市患雇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宇挫,老刑警劉巖苛吱,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異器瘪,居然都是意外死亡翠储,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門橡疼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來援所,“玉大人,你說我怎么就攤上這事欣除∽∈茫” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵历帚,是天一觀的道長滔岳。 經(jīng)常有香客問我,道長挽牢,這世上最難降的妖魔是什么谱煤? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮禽拔,結果婚禮上刘离,老公的妹妹穿的比我還像新娘。我一直安慰自己奏赘,他們只是感情好寥闪,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著磨淌,像睡著了一般疲憋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梁只,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天缚柳,我揣著相機與錄音,去河邊找鬼搪锣。 笑死秋忙,一個胖子當著我的面吹牛,可吹牛的內容都是我干的构舟。 我是一名探鬼主播灰追,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弹澎?” 一聲冷哼從身側響起朴下,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎苦蒿,沒想到半個月后殴胧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡佩迟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年团滥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片报强。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡灸姊,死狀恐怖,靈堂內的尸體忽然破棺而出躺涝,到底是詐尸還是另有隱情厨钻,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布坚嗜,位于F島的核電站,受9級特大地震影響诗充,放射性物質發(fā)生泄漏苍蔬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一蝴蜓、第九天 我趴在偏房一處隱蔽的房頂上張望碟绑。 院中可真熱鬧,春花似錦茎匠、人聲如沸格仲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凯肋。三九已至,卻和暖如春汽馋,著一層夾襖步出監(jiān)牢的瞬間侮东,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工豹芯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留悄雅,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓铁蹈,卻偏偏與公主長得像宽闲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350