基於Node.js的web框架,koa1只兼容ES5,koa2兼容ES6及之後。javascript
const Koa = requier("koa"); const koa = new Koa(); //koa.use註冊中間件(一個用來處理請求/修飾向服務器發起的請求的異步函數,參數爲ctx和next) //每個請求都會從上往下執行,當一箇中間件調用 next() 則該函數暫停並將控制傳遞給定義的下一個中間件。當在下游沒有更多的中間件執行後,堆棧將展開而且每一箇中間件恢復執行其上游行爲。 koa.use(async (ctx, next)=>{ //ctx上下文,是對request和response對象的一個封裝 console.log(0); await next(); //將控制權傳遞給下一個中間件 console.log(3); }); koa.use(async (ctx, next)=>{ await next(); console.log(2); }); koa.use(async (ctx, next)=>{ console.log(1); //當控制權傳遞到最後一箇中間件後,又會像冒泡同樣往上返回控制權 }); //0 1 2 3 koa.listen(3000); //監聽於3000端口
koa-router是處理路由的模塊,和koa它也是中間件模塊,在它上面註冊的中間件也會有控制權的傳遞和冒泡同樣返回控制權的行爲。css
const Koa = requier("koa"); const Router = requier("koa-router"); const koa = new Koa(); const router = new Router(); //將router模塊實例註冊到koa實例上 koa.use(router.routes()) .use(router.allowedMethods());
koa-router對路由的處理:router.method(url, 中間件1, 中間件2, ...)html
//接上例 const fs = requier("fs"); router.get("/", async ctx=>{ //來自跟路由的get請求會執行這個中間件 ctx.body = fs.readFileSync("index.html", "utf-8"); //ctx.body 響應主體 }); router.get("/demo", async ctx=>{ ctx.body = fs.readFileSync("demo.html", "utf-8"); }) router.post("/data", async ctx=>{ //處理post請求 })
建議將路由實例獨立成一個模塊,中間件獨立成另外一個模塊,模塊化處理。java
中間件:web
//middle.js const fs = require("fs"); module.exports = { "root" : async (ctx) => { ctx.body = fs.readFileSync("index.html", "utf8"); }, "demo" : async (ctx) => { ctx.body = fs.readFileSync("demo.html", "utf8"); } }
router實例:api
//router.js const Router = require("koa-router"); const router = new Router(); const dispose = require("./middle"); router.get("/", dispose.root); router.get("/demo", dispose.demo); module.exports = router;
最後再加上經常使用功能的模塊,註冊到koa實例上面去:跨域
const Koa = require("koa"); const router = require("./router"); const static = requier("koa-static"); //管理靜態資源(css,js,img文件等),指定靜態資源的根目錄,這樣在html引入文件的路徑中可用根目錄「/」表示指定的靜態資源的根目錄 const {join} = requier("path"); //合併路徑 const koaBody = require("koa-body"); //能夠經過ctx.request.body得到請求主體 const cors = requier("@koa/cors"); //設置容許跨域的模塊 const koa = new Koa(); koa.use(static(join(__dirname, "static"))) //指定文件所處目錄下的static文件夾爲靜態資源位置 .use(koaBody()) .use(cors()); koa.use(router.routes()) .use(router.allowedMethods()) .listen(3000, ()=>{ console.log("開始監聽3000端口"); })
模板引擎便於在中間件處理渲染頁面(配合ctx.render方法)時給頁面傳參,讓頁面根據參數的不一樣而呈現不一樣的內容。服務器
const Koa = require("koa"); const views = require("koa-views"); //管理模板引擎 const {join} = require("path"); const koa = new Koa(); koa.use(views(join(__dirname + '/views'), { extension: "pug" //使用pug模板引擎 })); koa.use(async ctx=>{ await ctx.render("index", { //將views目錄下的index.pug內容渲染到頁面中去 bool: 1 //往index.pug裏傳參 }); }).listen(3000, ()=>{ console.log("start to listen at 3000 port"); })
pug模板遵循嚴格的縮進,具體語法見:https://pug.bootcss.com/api/getting-started.htmlcors
// index.pug doctype html html head meta(charset="UTF-8") title simple body div.box#wrap wrap內容 div(class = bool ? "simple" : "complicated") 啦啦啦 input( type='checkbox',name='agreement',checked )