Express是一個極簡的Node.js Web框架。Express官網(wǎng)
學習了express之后玄妈,簡單實現(xiàn)了一個CRUD demo,整理了一些核心點和第三方中間件的使用髓梅。
- 引入express拟蜻,啟動一個服務
const express = require('express');
const app = express();
app.listen(3000, () => {
console.log('runing...')
})
- 托管靜態(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
...
- 路由的使用
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)
-
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
-
模板引擎使用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; }) })
-
md5加密
使用md5對用戶注冊和登錄的密碼進行加密npm i md5
const md5 = require('md5'); // 采用二次加密震缭,生產(chǎn)中一般會在第一次加密后拼接sign以提高安全性 password = md5(md5(password) + 'userManage');
-
保存登錄和注冊狀態(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;
-
統(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 }) })
-
數(shù)據(jù)庫
數(shù)據(jù)庫使用第三方庫 mongoosenpm 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