官網地址 >>javascript
koa 是由 Express 原班人馬打造的,致力於成爲一個更小、更富有表現力、更健壯的 Web 框架。使用 koa 編寫 web 應用,經過組合不一樣的 generator,能夠免除重複繁瑣的回調函數嵌套,並極大地提高錯誤處理的效率。koa 不在內核方法中綁定任何中間件,它僅僅提供了一個輕量優雅的函數庫,使得編寫 Web 應用變得駕輕就熟。html
Koa 應用是一個包含一系列中間件 generator 函數的對象。 這些中間件函數基於 request 請求以一個相似於棧的結構組成並依次執行。前端
Koa 的核心設計思路是爲中間件層提供高級語法糖封裝,以加強其互用性和健壯性,並使得編寫中間件變得至關有趣。java
Koa 包含了像 content-negotiation(內容協商)、cache freshness(緩存刷新)、proxy support(代理支持)和 redirection(重定向)等經常使用任務方法。node
# NPM
$ npm install koa
# Yarn
$ yarn add koa
複製代碼
代碼示例:git
const Koa = require('koa');
const app = new Koa();
// 對於任何請求,app將調用該異步函數處理請
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
console.log("Server running at http://127.0.0.1:3000");
複製代碼
瀏覽器訪問:「http://127.0.0.1:3000」,頁面出現「Hello world!」。github
app.listen(...)
其實是如下代碼的語法糖:web
const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
複製代碼
這意味着您能夠同時支持 HTTPS 和 HTTPS,或者在多個端口監聽同一個應用。mongodb
const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);
複製代碼
Koa Context 將 node 的 request
和 response
對象封裝在一個單獨的對象裏面。context 在每一個 request 請求中被建立,在中間件中做爲接收器(receiver)來引用,或者經過 this
標識符來引用:shell
app.use(async ctx => {
ctx; // is the Context
ctx.request; // is a koa Request
ctx.response; // is a koa Response
});
複製代碼
中間件 => koa2-cors
>> 下載:
# NPM
$ npm install koa2-cors
# YARN
$ yarn add koa2-cors
複製代碼
>> 使用:
const cors = require('koa2-cors');
app.use(cors());
複製代碼
中間件:koa-static
>> 下載:
# NPM
$ npm install koa-static
# YARN
$ yarn add koa-static
複製代碼
>> 使用:
// 1. 引入
const path = require('path');
const static = require('koa-static');
// 2. 使用
app.use(static(
path.join(__dirname, "./www")
));
// 3. 瀏覽器訪問
// => http://localhost:3000/images/koa.jpeg
複製代碼
路由是由一個URI和一個特定的HTTP 方法(GET、POST 等)組成,涉及到應用如何響應客戶端對某個網站節點的訪問。通俗的講 => 路由就是根據不一樣的URL 地址,加載不一樣的頁面實現不一樣的功能。 Koa 中,咱們使用 koa-router 實現路由配置。
# NPM
$ npm install koa-router
# YARN
$ yarn add koa-router
複製代碼
代碼示例:
const Koa = require('koa');
const router = require('koa-router')(); // 注意:引入的方式
const app = new Koa();
router.get('/', (ctx, next) => {
ctx.body = "Hello koa!";
})
router.get('/info', (ctx, next) => {
ctx.body = JSON.stringify({
name: "木子李",
job: "前端工程師",
email: "lihy_online@163.com",
origin: "四川成都"
});
});
app.use(router.routes());
app.use(router.allowedMethods());
/* 做用: 這是官方文檔的推薦用法,咱們能夠看到router.allowedMethods()用在了路由匹配 router.routes()以後,目的在於:根據ctx.status 設置 response 響應頭 */
app.listen(3000, () => {
console.log('server running at http://localhost:3000');
});
複製代碼
在koa2 中GET 傳值經過request 接收,可是接收的方法有兩種:query
和querystring
。
query
:返回的是格式化好的參數對象。querystring
:返回的是請求字符串。代碼示例:
router.get('/info', (ctx, next) => {
let url = ctx.url;
// 從request 中獲取GET 請求
let request = ctx.request;
let req_query = request.query;
let req_querystring = request.querystring;
// 從context 中直接獲取
let ctx_query = ctx.query;
let ctx_querystring = ctx.querystring;
ctx.body = {
url,
req_query,
req_querystring,
ctx_query,
ctx_querystring
}
});
複製代碼
效果顯示:
動態路由:
// 請求方式 => http://localhost/product/123
router.get('/product/:aid', async (ctx) => {
console.log(ctx.params); // { aid: '123' } // 獲取動態路由的數據
ctx.body = '商品頁面';
});
複製代碼
客戶端代碼:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<img src="http://localhost:3000/images/koa.jpeg" >
<script> // 1. 建立請求對象 let xhr = new XMLHttpRequest(); // 2. 配置請求 xhr.open("POST", "http://127.0.0.1:3000/login", true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.responseType = "json"; // 3. 發送請求 xhr.send(JSON.stringify({ username: "admin", password: "123" })); // 4. 監聽請求 xhr.onload = function() { if(xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.response); }else { console.log("err"); } } </script>
</body>
</html>
複製代碼
中間件 => koa-bodyparser
>> 下載:
# NPM
$ npm install koa-bodyparser
# YARN
$ yarn add koa-bodyparser
複製代碼
>> 使用:
// 1. 引入
const bodyParser = require('koa-bodyparser');
// 2. 使用
app.use(bodyParser());
// 3. 讀取
router.post('/login', async (ctx) => {
console.log(ctx.request.body);
});
複製代碼
"dependencies": {
"koa": "^2.11.0",
"koa-bodyparser": "^4.2.1",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"koa2-cors": "^2.0.6"
}
複製代碼
用戶接口:./router/user.js
// => 導入路由模塊
const router = require('koa-router')();
// => 處理路由
router.post('/login', (ctx, next) => {
console.log(`「登陸接口」 被調用!`)
ctx.body = {
code: 200,
message: "用戶登陸!"
};
next();
});
router.post('/register', (ctx, next) => {
console.log(`「註冊接口」 被調用!`)
ctx.body = {
code: 200,
message: "用戶註冊!"
};
next();
});
// => 導出路由配置
module.exports = router.routes();
複製代碼
訂單接口:./router/orders.js
// => 導入路由模塊
const router = require('koa-router')();
// => 處理路由
router.get('/', (ctx, next) => {
console.log(`「查詢訂單接口」 被調用!`)
ctx.body = {
code: 200,
message: "查詢訂單"
};
next();
});
router.get('/delete', (ctx, next) => {
console.log(`「刪除訂單接口」 被調用!`)
ctx.body = {
code: 200,
message: "刪除訂單"
};
next();
});
// => 導出路由配置
module.exports = router.routes();
複製代碼
合併接口:./router/index.js
const router = require('koa-router')();
const user = require('./user');
const orders = require('./orders');
router.use('/user', user);
router.use('/orders', orders);
module.exports = router;
複製代碼
調用接口:app.js
// => 導入模塊
const Koa = require('koa');
const cors = require('koa2-cors');
const bodyParser = require('koa-bodyparser');
const path = require('path');
const static = require('koa-static');
const router = require('./router');
const app = new Koa();
// => 處理跨域
app.use(cors());
// => 解析POST參數
app.use(bodyParser());
// => 處理路由
app.use(router.routes()).use(router.allowedMethods());
// => 處理靜態資源
app.use(static(
path.join(__dirname, "./www")
))
// => 監聽
app.listen(3000, () => {
console.log('server running at http://localhost:3000');
});
複製代碼
訪問數據庫以前,首先建立數據庫,而後在該數據庫下建立對應的用戶並設置權限。
數據庫中的 Schema, 爲數據庫對象的集合。 schema 是 mongoose 裏會用到的一種數據模式, 能夠理解爲表結構的定義; 每一個 schema 會映射到 mongodb 中的一個 collection, 它不具有 操做數據庫的能力。
const heroSchema = new mongoose.Schema({
name: string,
age: number
}, {
collection: "heros"
});
複製代碼
const HeroModel = mongoose.model("HeroModel", heroSchema, "heros");
複製代碼
> 創建鏈接
// 文件位置:./db/index.js
// => 導入模塊
const mongoose = require('mongoose');
// => URI > mongodb://用戶名:密碼@主機:端口/數據庫名稱
const MONGODB_URI = "mongodb://root:123@localhost:27017/mongo";
// => 鏈接數據庫
mongoose.connect(MONGODB_URI, { useNewUrlParser: true }, (err) => {
if (err) {
console.log('mongodb connect fail!');
return;
}
console.log("mongodb connect success!")
});
module.exports = mongoose;
複製代碼
> 構建Model
// 文件位置:./models/hero.js
const mongoose = require("../db");
const heroSchema = new mongoose.Schema({
name: {
type: String,
required: true,
index: true,
unique: true
},
age: {
type: Number,
required: true,
min: 18,
max: 65
},
tel: {
type: String,
required: true
},
gender: {
type: String,
default: "保密"
}
}, {
collection: "heros"
});
const Hero = mongoose.model("Hero", heroSchema, "heros");
module.exports = Hero;
複製代碼
提示:你能夠根據此模式構建多個Model
> 操做數據
// 文件位置:app.js
const HeroModel = require('./models/heros');
// => 存儲數據
let hero = new HeroModel({
name: "木子李",
age: 27,
tel: "17398888669",
gender: "男"
});
hero.save((err, res) => {
if(err) {
console.log(err);
return;
}
console.log(res);
})
// => 查詢數據
HeroModel.find((err, res) => {
if(err) {
console.log(err);
return;
}
console.log(res);
});
// => 修改數據
HeroModel.updateOne({name: "木子李"}, {age: 30}, (err, res) => {
if(err) {
console.log(err);
return;
}
console.log("修改爲功!");
});
// => 刪除數據
HeroModel.deleteOne({name: "木子李"}, (err, res) => {
if(err) {
console.log(err);
return;
}
console.log("刪除成功!");
})
複製代碼