node express基本使用(一)


這里 用的express 5 請注意

1. 創建一個新的路由器對象。

const router = express.Router([options])
mergeParams  // 保留來自父路由器的req.params值。如果父對象和子對象具有沖突的參數名,則以子對象的值為准。
caseSensitive //     啟用區分大小寫。 默認情況下禁用,將“ / Foo”和“ / foo”視為相同。
strict // 啟用嚴格路由。 默認情況下禁用,路由器將“ / foo”和“ / foo /”視為相同。

路由規則是app.use(path,router)定義的,router代表一個由express.Router()創建的對象,在路由對象中可定義多個路由規則。可是如果我們的路由只有一條規則時,可直接接一個回調作為簡寫,也可直接使用app.get或app.post方法。即
當一個路徑有多個匹配規則時,使用app.use()

// 很麻煩這樣寫
app.get("/home",callback)
app.get("/home/one",callback)
app.get("/home/second",callback)

// 可以創建一個router.js 專門用來一個路由匹配多個子路由
var router = express.Router()
router.get("/",(req,res)=>{
    res.send("/")
})
router.get("/one",(req,res)=>{
    res.send("one")
})
router.get("/second",(req,res)=>{
    res.send("second")
})
module.exports = router;

// 在app.js中導入router.js
var express = require('express')
var router = require("./router")
var app = express()
app.use('/home',router) //router路由對象中的路由都會匹配到"/home"路由后面

2.  app.use用法

app.use(path,callback)中的callback既可以是router對象又可以是函數
app.get(path,callback)中的callback只能是函數

// 中間件也可以使用多級 callback   anth()中要調用next() 否則不會往下走 
// callback中定義的const let 在下一個callback中是無法訪問的 要掛載到 req 或者 res 中
app.use('/admin/api/rest/:resourse', anth(), (req, res, next) => {
  const MODEL_NAME = require('inflection').classify(req.params.resourse)
  // const model = require(`../../models/${MODEL_NAME}`);
  // 為什么不使用 const   router 會訪問不到model 所以掛載到req上
  req.model = require(`../../models/${MODEL_NAME}`);
  next()
}, router)

3. 加載靜態資源

const path = require('path')
app.use('/uploads', express.static(path.join(__dirname, 'uploads')))

// 為了提供對靜態資源文件(圖片,css,js文件)的服務,請使用Express內置的中間函數express.static
uploads文件中靜態資源通過 http://localhost:3000/uploads/6abe1df86915ae97a3ee28537a5f8cfa 來訪問 

// 為了給靜態資源文件創建一個虛擬的文件前綴(文件系統中不存在),可以使用express.static函數指定一個虛擬的靜態目錄
app.use('/static', express.static('public'))
// 使用‘/static’作為前綴來加載public文件夾下的文件了

4. 不同模塊的接口分模塊開發

module.exports = (app) => {
const express = require('express')
const router = express.Router({
mergeParams: true // 保留來自父路由器的req.params值。如果父對象和子對象具有沖突的參數名,則以子對象的值為准。
}) // 創建express 的子路由, 分模塊存儲接口
router.get('/', async(req, res) => {
const items = await req.model.find().limit(10) // find 相當於select 進行查詢操作
res.send(items)
})
app.use('/admin/api/rest/:resourse', router)
} // 在這個文件里你可以拿到app

// 在 index.js 中引入
require('./routes/admin')(app)

5.  使用CRUD 共工接口

/**
 * 共享接口 CRUD
 * 假如 有兩個模板 功能都是增刪改查 接口都是相似的操作 就可以使用共享接口
 * app.use('/admin/api/rest/:resourse', router)
 * 需要自己加一個 rest 防止接口沖突
 * 后面是動態的參數  也就是自己的模型名 數據庫表名 == 接口名
 * req.params.resourse  可以拿到動態參數 也就是表名  resourse 是自己定義的 也可以是別的
 * 然后 在接口里面 引入參數對應的模型名  
 
 */
 module.exports = (app) => {
    const express = require('express')
    const anth = require('../../utils/auth')
    const router = express.Router({
            mergeParams: true // 保留來自父路由器的req.params值。如果父對象和子對象具有沖突的參數名,則以子對象的值為准。
        }) // 創建express 的子路由, 分模塊存儲接口
    router.post('/', async(req, res) => {
        const model = await req.model.create(req.body) // 往mongoodb添加數據
        res.send(model)
    })
    router.get('/', async(req, res) => {
        // populate 方法 返回關聯對象id 轉換成 對象 
        const queryOption = {}
        if (req.model.modelName == 'Category') {
            queryOption.populate = 'parent'
        }
        if (req.model.modelName == 'Article') {
            queryOption.populate = 'categories'
        }
        const items = await req.model.find().setOptions(queryOption).limit(10) // find 相當於select  進行查詢操作 populate 查找綁定對象
        res.send(items)
    })
    router.get('/:id', async(req, res) => {
        const model = await req.model.findById(req.params.id) // find 相當於select  進行查詢操作
        res.send(model)
    })
    router.put('/:id', async(req, res) => {
        const model = await req.model.findByIdAndUpdate(req.params.id, req.body) // find 相當於select  進行查詢操作
        res.send({ msg: '修改成功' })
    })
    router.delete('/:id', async(req, res) => {
        await req.model.findByIdAndDelete(req.params.id) // find 相當於select  進行查詢操作
        res.send({ msg: '刪除成功' })
    })

    //  使用 rest 防止接口沖突 加上私有前綴
    //  /admin/api/rest/:resourse 中 /:resourse 綁定動態名稱  resourse 是自己定義的 也可以是別的
    //  前台傳得 http://localhost:3000/admin/api/rest/items
    //  req.params.resourse  可以拿到動態參數 也就是表名 也就是前台接口中items
    app.use('/admin/api/rest/:resourse', (req, res, next) => {
    
        // *inflection插件   inflection.classify( 'message_bus_properties' );//=== 'MessageBusProperty'  會把單詞 復數 轉換成 單數 因為mongoose中表名是單數  而接口中都是復數  轉一下子
        const MODEL_NAME = require('inflection').classify(req.params.resourse)
        
        // const model = require(`../../models/${MODEL_NAME}`);
        // 為什么不使用 const   router 會訪問不到 model 所以掛載到req上
        req.model = require(`../../models/${MODEL_NAME}`);
        next()
    }, router)
}

6. 圖片文件上傳 中間件multer

const multer = require('multer')
// dest 目標地址  文件存放在哪里
const upload = multer({ dest: __dirname + '/../../uploads' })
// upload.single() 接受名稱為的單個文件fieldname。單個文件將存儲在中req.file。
app.post('/admin/api/upload', upload.single('file'), async(req, res) => {
  const file = req.file
  // 如果想讓前台查看上傳圖片要拼接文件路徑返給前台 file.filename就是存儲的文件名 uploads是存儲的文件夾
  file.url = `http://localhost:3000/uploads/${file.filename}`
  res.send(file)
})

7. 對存儲用戶密碼進行加密解密操作 bcryptjs

const bcryptjs = require('bcryptjs')
// val 要加密的數據 也就是密碼   10 就要加密的等級 最好是10-12之間 12以后加密跟解密性能慢 但是安全度高
var pwd = bcryptjs'.hashSync(val, 10)
// 然后存到數據庫表中

// 登陸的時候 先根據前台傳的 name 去數據庫中那條數據   name 一般是唯一的 然后在取出密碼
// 密碼校驗的操作  password 是用戶傳來的密碼  user.password 是數據庫存儲的加密的密碼
var flag = bcryptjs.compareSync(password, user.password) // 返回 true 和 false
// true 返回正確 false 返回錯誤

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM