在瞭解什麼是中間件以前,咱們先實現一個帶路由的koa應用。node
要新建一個帶路由的koa應用特別容易,跟着個人步驟,幾分鐘就能完成。
首先,咱們打開命令行,新建一個koa-middleware目錄,進入這個目錄。npm
mkdir koa-middleware
cd koa-middleware/
複製代碼
而後,初始化package.json文件,執行init命令以後一路回車就ok。以後安裝咱們須要用到的koa和koa-router依賴。json
npm init
npm i koa koa-router --save
複製代碼
而後新建一個app.js文件,這個文件是應用的入口,在這裏編寫代碼瀏覽器
// app.js
const Koa = require('koa');
const router = require('koa-router')();
const app = new Koa();
router.get('/', async (ctx) => {
ctx.body = "這是首頁";
})
router.get('/userCenter', async (ctx) => {
ctx.body = '這是一個用戶頁面';
})
app.use(router.routes());
app.listen(3000);
複製代碼
node app
複製代碼
以後打開命令行,執行node app命令,打開瀏覽器訪問localhost:3000,就能夠看到咱們的頁面,改變url,就能夠切換頁面,這樣咱們的路由功能就實現了。bash
koa中間件指的是,匹配路由以前或者以後作的一系列操做。在上面這個例子裏,router.get這個函數有兩個參數,第一個參數就是匹配的路徑,第二個參數是一個函數。在這個函數裏,咱們返回了一個body是「這是首頁」的頁面。這就是咱們匹配路由以後作的操做,也就是中間件。在中間件裏咱們能夠作不少事情,好比:app
中間件也分幾種類型,他們分別是:koa
假設咱們如今有這麼一個需求,在全部的路由裏都打印出當前的時間。咱們能夠選擇每一個路由單獨寫一個方法來打印日期,但這是不可取的。這時咱們能夠用中間件來寫。async
const Koa = require('koa');
const router = require('koa-router')();
const app = new Koa();
// 用於在每次匹配路由前都打印一次當前時間的中間件
app.use(async (ctx,next)=>{
console.log(new Date());
await next();// 繼續向下匹配
})
router.get('/', async (ctx) => {
ctx.body = "這是首頁";
})
router.get('/userCenter', async (ctx) => {
ctx.body = '這是一個用戶頁面';
})
app.use(router.routes());
app.listen(3000);
複製代碼
這時,咱們每切換一次url,就能夠在控制檯打印一次當前時間(注意是控制檯打印,不是瀏覽器)。
這就是應用級中間件,寫法是app.use(),注意必須調用next()方法,纔會有後續的匹配路由,否則頁面就會返回404。函數
應用級中間件是匹配全部的路由,即無論訪問哪一個路由以前,都會調用一次。那麼若是咱們只想在訪問某個路由以前作一些操做,該怎麼辦呢?這裏咱們用到的是路由級中間件,代碼以下:學習
const Koa = require('koa');
const router = require('koa-router')();
const app = new Koa();
router.get('/',async(ctx,next)=>{
console.log('這是首頁');
await next();
})
router.get('/', async (ctx) => {
ctx.body = "這是首頁";
})
router.get('/userCenter', async (ctx) => {
ctx.body = '這是一個用戶頁面';
})
app.use(router.routes());
app.listen(3000);
複製代碼
能夠看到,咱們訪問了兩次首頁路由,第一次作了一些操做以後,調用next(),第二次再訪問,再作另一些操做。這樣就能夠訪問具體某個路由前作一些操做了。
若是用戶在瀏覽器輸入了錯誤的url,瀏覽器會跳轉到404界面,但瀏覽器自帶的界面通常很醜,不夠美觀,因此咱們要本身設計符合咱們項目主題的404界面,這個時候就要用到錯誤處理中間件了。
const Koa = require('koa');
const router = require('koa-router')();
const app = new Koa();
app.use(async (ctx, next) => {
next();
if (ctx.status == 404) {
ctx.status = 404;
ctx.body = "這是一個很是美觀的404頁面"
}
});
router.get('/', async (ctx) => {
ctx.body = "這是首頁";
})
router.get('/userCenter', async (ctx) => {
ctx.body = '這是一個用戶頁面';
})
app.use(router.routes());
app.listen(3000);
複製代碼
koa有不少第三方的中間件,好比koa-static,koa-bodyparser等,咱們使用這些第三方中間件的時候,要先下載下來,好比:
npm i koa-static koa-bodyparser --save
複製代碼
以後先引入再調用
const static = require('koa-static');
const staticPath = './static';
app.use(static(
path.join( __dirname, staticPath)
));
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
複製代碼
在瞭解koa中間件執行順序以前,先來看這樣一段代碼:
const Koa = require('koa');
const app = new Koa();
app.use(async(ctx,next) =>{
console.log(1);
await next();
console.log(2);
})
app.use(async(ctx,next) =>{
console.log(3);
await next();
console.log(4);
})
app.use(async(ctx,next) =>{
console.log(5);
ctx.body = 'hello';
})
app.listen(3000);
複製代碼
咱們看到這張圖,能夠這麼理解:
洋蔥模型很是關鍵,它決定了咱們寫的程序的運行順序,好比咱們要寫錯誤處理中間件,就要把response的部分寫到next()函數以後,讓他在路由匹配完成以後再執行。
const Koa = require('koa');
const router = require('koa-router')();
const app = new Koa();
app.use(async (ctx, next) => {
next();
if (ctx.status == 404) {
ctx.status = 404;
ctx.body = "這是一個很是美觀的404頁面"
}
});
router.get('/', async (ctx) => {
ctx.body = "這是首頁";
})
router.get('/userCenter', async (ctx) => {
ctx.body = '這是一個用戶頁面';
})
app.use(router.routes());
app.listen(3000);
複製代碼
本文從搭建一個帶路由的koa應用講起,以後引出了koa中間件的概念,再介紹了幾種經常使用的中間件,最後解釋了中間件的執行順序和洋蔥模型,很適合剛瞭解koa的朋友學習,若是對你有幫助,就分享出去吧。