1.中間件分類
應用程序級別中間件
????????通過?app.use()
?或?app.METHOD()
(如?app.get
)綁定的中間件,作用于整個應用程序。例如
記錄請求日志、解析請求體等全局功能。例如:
app.use((req, res, next) => {console.log('Request URL:', req.url);next();
});
路由級別中間件
????????綁定到?router.use()
?或?router.METHOD()
?的中間件,僅對特定路由生效。常用于分組路由的
共享邏輯(如權限校驗)。例如:
const router = express.Router();
router.use((req, res, next) => {if (req.user.isAdmin) next();else res.status(403).send('Forbidden');
});
錯誤處理中間件
????????接收四個參數?(err, req, res, next)
,用于捕獲并處理同步/異步錯誤。需定義在中間件鏈
末尾。例如:
app.use((err, req, res, next) => {console.error(err.stack);res.status(500).send('Server Error');
});
內置中間件
Express 提供的開箱即用功能,如?express.json()
?解析 JSON 請求體:
app.use(express.json());
第三方中間件
通過 npm 安裝的中間件,例如?cors
?處理跨域、helmet
?增強安全性:
app.use(require('cors')());
2.中間件的使用
app.js文件中:
const express = require("express");const app = express();
const routerIndex=require("./router/index")
const videoRouter=require("./router/vedio")
const PORT = process.env.PORT || 3000;// 設置日志中間件 中間件代碼的位置很有講究 必須是所有路由的前面才行
app.use((req, res, next) => {console.log(`${req.method} ${req.url},${Date.now()}`);// 繼續處理下一個中間件或路由處理函數next();
},function(req, res, next) { console.log('輸出了日志,然后就可以執行這里面的代碼,可以寫多個這樣的函數,然后使用next()執行下一個函數');next();
});
// 當有四個參數時,會默認這是個錯誤處理中間件
app.use((err,req,res,next)=>{console.log(err,'錯誤信息');res.status(500).send("服務器錯誤")
})
// 掛載路由 所有的路由前面都要加 /api,相當于vue的反向代理
app.use('/api',routerIndex);
app.use('/vedio',videoRouter)
// 掛載統一處理服務端錯誤中間件
// app.use(errorHandler());// all 方法,可以處理 /xx 路徑傳過來的所有請求方法都可以觸發,不管時get、post、put請求都會觸發它
app.all('/xx',(req,res)=>{res.send('xx')
})app.listen(PORT, () => {console.log(`Server is running at http://localhost:${PORT}`);
});
在app.js文件同級的router文件夾下的index.js:
const express = require('express')const router = express.Router()router.get('/',(req,res)=>{console.log(req.method);res.send('/index')
})
router.get('/users',(req,res)=>{console.log(req.method);res.send('/users')
})module.exports = router
在app.js文件同級的router文件夾下的vedio.js:
const express =require('express')
const router=express.Router()
// 這里的路由不是前端的跳轉頁面路由,而是后端的接口路由路徑
router.get('/list',(req,res)=>{console.log('list');res.send('list')
})
module.exports=router
3.路由
// 可以匹配正則,/us+er表示匹配多個s疊加的路徑,比如/usser、/ussser
app.get('/us+er',(req,res)=>{res.send(`${req.method} ${req.url}`)
})
獲取路由參數:
router.get('/list/:id',(req,res)=>{// 獲取路由參數console.log(req.params.id);res.send('list')
})
還可以鏈式調用:
router.get('/list/:id/are/:age',(req,res)=>{// 獲取路由參數console.log(req.params.id); // {id:2,age:3}res.send('list')
})
.post('/vedio',(req,res)=>{res.send('list')
})
使用res.render渲染:
// app.js文件
const express = require("express");
const app = express();
const path = require('path');
// 設置模板引擎(以 EJS 為例)
app.set('view engine', 'ejs');
// 設置視圖文件目錄
app.set('views', path.join(__dirname, 'views'));
const routerIndex=require("./router/index")
// 所有的路由前面都要加 /api,相當于vue的反向代理
app.use('/api',routerIndex);// router/index.js文件
const express = require('express')
const router = express.Router()
router.get('/',(req,res)=>{console.log(req.method);// res.render 是服務器端渲染,頁面跳轉到views/test/index.html頁面中 res.render('test/index', { name: 'Express 路由1' });// res.send('/index')
})
module.exports = router// views/test/index.ejs文件
<!DOCTYPE html>
<html lang="zh-CN"><head><metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title><%= name %></title></head><body><h1>Hello, <%= name %></h1></body><script>function corsGetData() {alert("dsafdsafdsafsda");}</script>
</html>// 安裝ejs
npm install ejs
效果:(請求?http://127.0.0.1:3000/api/?直接渲染頁面)
其他的響應方法:
// 這里的路由不是前端的跳轉頁面路由,而是后端的接口路由路徑
router.get('/list/:id',(req,res)=>{// 獲取路由參數console.log(req.params.id);// 下載文件 提示客戶端下載文件res.download('./files/report.pdf')// 結束響應過程 不發送任何數據,直接結束響應// 通常用于簡單響應或與 res.write() 配合使用res.end()// 發送 JSON 格式的響應 自動設置 Content-Type 為 application/jsonres.json({ message: 'Hello World' })// 重定向到指定的 URL 默認發送 302 狀態碼res.redirect('/login')// 渲染模板引擎視圖res.render('index.ejs', { title: '首頁' })// res.render 是服務器端渲染,頁面跳轉到views/test/index.html頁面中 res.render('test/index', { name: 'Express 路由1' });// 發送文件作為響應res.sendFile('/views/index.html')// 設置響應狀態碼并發送其字符串表示作為響應體res.sendStatus(404) // 會發送 404 狀態碼和 "Not Found" 字符串res.send('list')
})
4. 設置跨域和記錄日志
// 跨域
npm i cors
// 請求日志中間件
npm i morgan
在app.js文件中:
const cors =require('cors')
const morgan =require('morgan')
app.use(cors())
app.use(morgan('dev'))// 只記錄開發時的日志