1.安裝
npm i koa
2.簡單使用
const Koa = require('koa')
const app = new Koa()
app.use( async ( ctx ) => {
ctx.body = 'hello koa2'
})
app.listen(3000)
3.koa的腳手架
npm i -g koa-generator
3.1 創(chuàng)建koa2項目
koa2 xxx(文件名)

3.2 四種啟動方式

1.npm start
該啟動命令也是我們創(chuàng)建項目后使用的啟動命令。
注意:該命令啟動的項目,更改服務(wù)端接口后服務(wù)不會自啟動。
2.npm run dev
該啟動命令啟動項目后,更改服務(wù)端接口后服務(wù)會自啟動。
npm run dev啟動項目后用的是nodemon,是監(jiān)聽。
4.koa2中間件
通俗的講:中間件就是匹配路由之前或者匹配路由完成做的一系列的操作,我們就可以把它叫做中間件。
在express中間件(Middleware) 是一個函數(shù),它可以訪問請求對象(request object (req)), 響應(yīng)對象(response object (res)), 和 web 應(yīng)用中處理請求-響應(yīng)循環(huán)流程中的中間件,一般被命名為 next 的變量。在Koa中中間件和express有點類似。
中間件的功能包括:
執(zhí)行任何代碼。
修改請求和響應(yīng)對象。
終結(jié)請求-響應(yīng)循環(huán)。
調(diào)用堆棧中的下一個中間件。
如果我的get、post回調(diào)函數(shù)中,沒有next參數(shù),那么就匹配上第一個路由,就不會往下匹配了。如果想往下匹配的話,那么需要寫next()
4.1 應(yīng)用級中間件
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
app.use(async (ctx,next)=>{
console.log(new Date());
await next();
})
router.get('/', function (ctx, next) {
ctx.body="Hello koa";
})
router.get('/news',(ctx,next)=>{
ctx.body="新聞頁面"
});
app.use(router.routes()); //作用:啟動路由
app.use(router.allowedMethods()); //作用: 當(dāng)請求出錯時的處理邏輯
app.listen(3000,()=>{
console.log('starting at port 3000');
});
4.2 路由中間件
router.get('/', async(ctx, next)=>{
console.log(1)
next()
})
router.get('/', function (ctx) {
ctx.body="Hello koa";
})
4.3 錯誤處理中間件
app.use(async (ctx,next)=> {
next();
if(ctx.status==404){
ctx.status = 404;
ctx.body="這是一個404頁面"
}
});
4.4 第三方中間件
const static = require('koa-static');
const staticPath = './static';
app.use(static(
path.join( __dirname, staticPath)
))
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
5.koa路由
路由(Routing)是由一個 URI(或者叫路徑)和一個特定的 HTTP 方法(GET、POST 等)組成的,涉及到應(yīng)用如何響應(yīng)客戶端對某個網(wǎng)站節(jié)點的訪問。
通俗的講:路由就是根據(jù)不同的URL地址,加載不同的頁面實現(xiàn)不同的功能。
Koa中的路由和Express有所不同,在Express中直接引入Express就可以配置路由,但是在Koa中我們需要安裝對應(yīng)的koa-router路由模塊來實現(xiàn)。
安裝: npm install --save koa-router
const Koa = require('koa');
const router = require('koa-router')(); //注意:引入的方式
const app = new Koa();
router.get('/', function (ctx, next) {
ctx.body="Hello koa";
})
router.get('/news,(ctx,next)=>{
ctx.body="新聞page"
});
app.use(router.routes()); //作用:啟動路由
app.use(router.allowedMethods()); // 作用: 這是官方文檔的推薦用法,我們可以看到router.allowedMethods()用在了路由匹配router.routes()之后,所以在當(dāng)所有路由中間件最后調(diào)用.此時根據(jù)ctx.status設(shè)置response響應(yīng)頭
app.listen(3000,()=>{
console.log('starting at port 3000');
});
5.1 GET請求獲取數(shù)據(jù)
在ko2a中,獲取GET請求數(shù)據(jù)源頭是koa中request對象中的query方法或querystring方法,query返回是格式化好的參數(shù)對象,querystring返回的是請求字符串,由于ctx對request的API有直接引用的方式,所以獲取GET請求數(shù)據(jù)有兩個途徑。
1.是從上下文中直接獲取
請求對象ctx.query,返回如 { a:1, b:2 }
請求字符串 ctx.querystring,返回如 a=1&b=2
2.是從上下文的request對象中獲取
請求對象ctx.request.query,返回如 { a:1, b:2 }
請求字符串 ctx.request.querystring,返回如 a=1&b=2
5.2 POST請求獲取數(shù)據(jù)
對于POST請求的處理,koa2沒有封裝獲取參數(shù)的方法,需要通過解析上下文context中的原生node.js請求對象req,將POST表單數(shù)據(jù)解析成query string(例如:a=1&b=2&c=3),再將query string 解析成JSON格式(例如:{"a":"1", "b":"2", "c":"3"})
注意:ctx.request是context經(jīng)過封裝的請求對象,ctx.req是context提供的node.js原生HTTP請求對象,同理ctx.response是context經(jīng)過封裝的響應(yīng)對象,ctx.res是context提供的node.js原生HTTP請求對象。
5.3 koa-bodyparser模塊
安裝:npm install --save koa-bodyparser
通過ctx.request.body獲取post提交的數(shù)據(jù)
var Koa = require('koa');
var bodyParser = require('koa-bodyparser');
var app = new Koa();
app.use(bodyParser());
app.use(async ctx => {
ctx.body = ctx.request.body;
});
6.koa-static靜態(tài)資源中間件
一個http請求訪問web服務(wù)靜態(tài)資源,一般響應(yīng)結(jié)果有三種情況
訪問文本,例如js,css,png,jpg,gif
訪問靜態(tài)目錄
找不到資源,拋出404錯誤
koa-static主要是用于訪問靜態(tài)資源
安裝:npm install --save koa-static
const static = require('koa-static');
app.use(static(
path.join( __dirname, 'public')
))
這個時候靜態(tài)資源就可以被koa中間件解析了
7.Koa2中 Cookie的使用
-cookie 是存儲于訪問者的計算機(jī)中的變量??梢宰屛覀冇猛粋€瀏覽器訪問同一個域名的時候共享數(shù)據(jù)。
-HTTP是無狀態(tài)協(xié)議。簡單地說,當(dāng)你瀏覽了一個頁面,然后轉(zhuǎn)到同一個網(wǎng)站的另一個頁面,服務(wù)器無法認(rèn)識到這是同一個瀏覽器在訪問同一個網(wǎng)站。每一次的訪問,都是沒有任何關(guān)系的。
-Cookie是一個簡單到爆的想法:當(dāng)訪問一個頁面的時候,服務(wù)器在下行HTTP報文中,命令瀏覽器存儲一個字符串; 瀏覽器再訪問同一個域的時候,將把這個字符串?dāng)y帶到上行HTTP請求中。第一次訪問一個服務(wù)器,不可能攜帶cookie。 必須是服務(wù)器得到這次請求,在下行響應(yīng)報頭中,攜帶cookie信息,此后每一次瀏覽器往這個服務(wù)器發(fā)出的請求,都會攜帶這個cookie。
7.1 Koa中設(shè)置Cookie的值
ctx.cookies.set(name, value, [options])
通過 options 設(shè)置 cookie name 的 value :
options 名稱 options 值
maxAge 一個數(shù)字表示從 Date.now() 得到的毫秒數(shù)
expires cookie 過期的 Date
path cookie 路徑, 默認(rèn)是'/'
domain cookie 域名
secure 安全 cookie 默認(rèn)false,設(shè)置成true表示只有 https可以訪問
httpOnly 是否只是服務(wù)器可訪問 cookie, 默認(rèn)是 true
overwrite 一個布爾值,表示是否覆蓋以前設(shè)置的同名的 cookie (默認(rèn)是 false). 如果是 true, 在同一個請求中設(shè)置相同名稱的所有 Cookie(不管路徑或域)是否在設(shè)置此Cookie 時從 Set-Cookie 標(biāo)頭中過濾掉。
7.2 Koa中獲取Cookie的值
ctx.cookies.get('name');
7.3 Koa中設(shè)置中文Cookie
console.log(new Buffer('hello, world!').toString('base64'));// 轉(zhuǎn)換成base64字符串:aGVsbG8sIHdvcmxkIQ==
console.log(new Buffer('aGVsbG8sIHdvcmxkIQ==', 'base64').toString());// 還原base64字符串:hello, world!
8.Koa2中Session
session是另一種記錄客戶狀態(tài)的機(jī)制,不同的是Cookie保存在客戶端瀏覽器中,而session保存在服務(wù)器上。
當(dāng)瀏覽器訪問服務(wù)器并發(fā)送第一次請求時,服務(wù)器端會創(chuàng)建一個session對象,生成一個類似于key,value的鍵值對, 然后將key(cookie)返回到瀏覽器(客戶)端,瀏覽器下次再訪問時,攜帶key(cookie),找到對應(yīng)的session(value)。 客戶的信息都保存在session中
8.1 koa-session的使用
安裝:npm install koa-session --save
8.2 引入koa-session
const session = require('koa-session');
8.3 設(shè)置官方文檔提供的中間件
app.keys = ['some secret hurr'];
const CONFIG = {
key: 'koa:sess', //cookie key (default is koa:sess)
maxAge: 86400000, // cookie的過期時間 maxAge in ms (default is 1 days)
overwrite: true, //是否可以overwrite (默認(rèn)default true)
httpOnly: true, //cookie是否只有服務(wù)器端可以訪問 httpOnly or not (default true)
signed: true, //簽名默認(rèn)true
rolling: false, //在每次請求時強(qiáng)行設(shè)置cookie,這將重置cookie過期時間(默認(rèn):false)
renew: false, //(boolean) renew session when session is nearly expired,
};
app.use(session(CONFIG, app));
8.4 使用
設(shè)置值 ctx.session.username = "張三";
獲取值 ctx.session.username
9.Koa中Cookie和Session區(qū)別
1、cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙
考慮到安全應(yīng)當(dāng)使用session。
3、session會在一定時間內(nèi)保存在服務(wù)器上。當(dāng)訪問增多,會比較占用你服務(wù)器的性能
考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用COOKIE。
4、單個cookie保存的數(shù)據(jù)不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
10.Koa2上傳圖片模塊koa-multer
koa-multer是一個 node.js 中間件,用于處理 multipart/form-data 類型的表單數(shù)據(jù),它主要用于上傳文件。它是寫在 busboy 之上非常高效。
注意: Multer 不會處理任何非 multipart/form-data 類型的表單數(shù)據(jù),意思就是我們要上傳圖片必須在form表單上面加 multipart/form-data
安裝:npm install --save koa-multer
10.1 引入配置koa-multer模塊
const multer = require('koa-multer');
//配置
var storage = multer.diskStorage({
//文件保存路徑
destination: function (req, file, cb) {
cb(null, 'public/uploads/') //注意路徑必須存在
},
//修改文件名稱
filename: function (req, file, cb) {
var fileFormat = (file.originalname).split(".");
cb(null,Date.now() + "." + fileFormat[fileFormat.length - 1]);
}
})
//加載配置
var upload = multer({ storage: storage })
10.2 使用koa-multer
router.post('/doAdd', upload.single('face'), async (ctx, next) => {
ctx.body = {
filename: ctx.req.file.filename,//返回文件名
body:ctx.req.body
}
});
10.3 使用koa-multer 上傳多個圖片
前臺表單:后臺:
router.post('/doAdd', upload.fields([{ name: 'pic', maxCount: 1 }, { name: 'aaa', maxCount: 1 }]),async (ctx)=>{
console.log(ctx.req.files);
})
注意Form表單加上enctype="multipart/form-data"
11. koa2分頁
11.1 數(shù)據(jù)庫分頁查詢數(shù)據(jù)的原理算法
規(guī)則:規(guī)定每頁20條數(shù)據(jù)的查詢方式
查詢第一頁(page=1):
db.表名.find().skip(0).limit(20)
查詢第二頁(page=2):
db.表名.find().skip(20).limit(20)
查詢第三頁(page=3):
db.表名.find().skip(40).limit(20)
總結(jié):分頁查詢的sql語句
db.表名.find().skip((page-1)*pageSize).limit(pageSize)
11.2 數(shù)據(jù)庫分頁方法封裝
find方法封裝
db.collection(collectionName).find(json1,{fields:attr}).skip(slipNum).limit(pageSize);
count方法封裝
var result= db.collection(collectionName).count(json);
result.then(function(data){
resolve(data);
})
12.koa2如何允許跨域
12.1 安裝 koa2-cors
npm install --save koa2-cors
12.2 引入 koa2-cors 并且配置中間件
var Koa = require('koa');
var cors = require('koa2-cors');
var app = new Koa();
app.use(cors());
13.Koa2設(shè)置全局變量
有時候我們需要設(shè)置一些全局的變量,在各個路由模塊中使用,下面我們看看那Koa2如何設(shè)置全局變量,以及Koa2中如何和設(shè)置全局模板數(shù)據(jù)
Koa中設(shè)置全局變量可以通過 ctx.state.變量名 來設(shè)置 如下:
router.use(async (ctx,next)=>{
//全局的G變量
ctx.state.G={
url:'http://www.itying.com',
userinfo:ctx.session.userinfo,
prevPage:ctx.request.headers['referer'] /*上一頁的地址*/
}
})
在路由中獲取全局變量也是通過 ctx.state.變量名 來獲取
我們通過 ctx.state.變量 設(shè)置的全局變量可以直接在模板用使用哦
如上代碼: 如果在其他模塊中使用變量 直接通過 ctx.state.G.url來調(diào)用
如果在模板中使用直接通過 <%=url%> 來獲取
14.Koa2 RESTful Api接口
14.1 一個好的Koa2 RESTful Api接口設(shè)計必須考慮以下幾點
1.協(xié)議:建議使用更安全的https協(xié)議
2.域名:盡量部署在專屬域名下面,比如https://a.itying.com https://api.itying.com
3.應(yīng)該將api的版本號放入URl中:
(1)比如: https://a.itying.com/api1/newslist https://a.itying.com/api2/newslist
(2)比如: https://a1.itying.com https://a2.itying.com
4.路徑:在RESTful架構(gòu)中,每個網(wǎng)址代表一種資源(resource),所以網(wǎng)址中建議不能有動詞,只能有名詞,而且所用的名詞往往與數(shù)據(jù)庫的表格名對應(yīng)。一般來說,數(shù)據(jù)庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應(yīng)該使用復(fù)數(shù)。
5.http請求數(shù)據(jù)的方式:(7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)
GET(SELECT):從服務(wù)器取出資源(一項或多項)。
POST(CREATE):在服務(wù)器新建一個資源。
PUT(UPDATE):在服務(wù)器更新資源(客戶端提供改變后的完整資源)。
DELETE(DELETE):從服務(wù)器刪除資源。
還有三個不常用的HTTP請求方式。
HEAD:獲取資源的元數(shù)據(jù)。
OPTIONS:獲取信息,關(guān)于資源的哪些屬性是客戶端可以改變的。
PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供改變的屬性)。
6、過濾方式、請求數(shù)據(jù)方式、返回數(shù)據(jù)、安全。
14.2 Koa2 RESTful Api接口 (get post put delete) 代碼演示
router.get('/catelist',async (ctx)=>{
var result=await DB.find('articlecate',{})
//console.log(result);
ctx.body={
result:result
};
})
//增加購物車數(shù)據(jù)
router.post('/addCart',async (ctx)=>{
//接收客戶端提交的數(shù)據(jù) 、主要做的操作就是增加數(shù)據(jù)
console.log(ctx.request.body);
ctx.body={
"success":true,
"message":'增加數(shù)據(jù)成功'
};
})
//修改用餐人數(shù)的接口
router.put('/editPeopleInfo',async (ctx)=>{
//接收客戶端提交的數(shù)據(jù) 、主要做的操作就是修改數(shù)據(jù)
console.log(ctx.request.body);
ctx.body={
"success":true,
"message":'修改數(shù)據(jù)成功'
};
})
//用于刪除數(shù)據(jù)源
router.delete('/deleteCart',async (ctx)=>{
//接收客戶端提交的數(shù)據(jù) 、主要做的操作就是刪除數(shù)據(jù)的操作
console.log(ctx.query);
ctx.body={
"success":true,
"message":'刪除數(shù)據(jù)成功'
};
})
15.koa2 網(wǎng)站開啟gzip壓縮
15.1 安裝koa-compress中間件
cnpm install koa-compress --save
15.2 配置koa-compress中間件
const koa = require('koa');
const compress = require('koa-compress');
const app = koa();
const options = { threshold: 2048 };
app.use(compress(options));
內(nèi)容引用:https://www.itying.com/koa/article-index-id-79.html