koa學習筆記:
文章目錄
- Koa2環境準備
- 安裝koa2
- kao2 async/await使用教程
- koa2目錄結構分析
- Koa2路由 以及 路由get傳值
- Koa2中 Cookie的使用
- Koa2中Session koa-session的使用
- koa2 art-template高性能模板引擎的使用
- Koa2模板引擎Ejs使用教程
- Koa2上傳圖片模塊koa-multer的使用
- kao2實現jsonp koa-jsonp模塊
- Koa2 分頁插件 jqPaginator_koa結合jquery分頁插件實現數據分頁
- Koa2富文本編輯器ueditor的配置使用- Koa2 ueditor
- koa2如何允許跨域_koa2跨域模塊koa2-cors
- Koa中設置全局變量
- Koa2中使用socket.io
- Koa2中集成GraphQl實現 Server API 接口
- koa2 301重定向,koa2 302重定向
- koa2 網站開啓gzip壓縮 ,koa-compress實現網頁gizp壓縮
文章來源:
https://www.itying.com/koa/article-index-id-80.html
Koa2環境準備
因爲node.js v7.6.0開始完全支持async/await,不需要加flag,所以node.js環境都要7.6.0以上
node.js環境: 版本v7.6以上
直接安裝node.js 7.6:node.js官網地址https://nodejs.org
**nvm管理多版本node.js:**可以用nvm 進行node版本進行管理
Mac系統安裝nvm https://github.com/creationix/nvm#manual-install
windows系統安裝nvm https://github.com/coreybutler/nvm-windows
Ubuntu系統安裝nvm https://github.com/creationix/nvm
**npm 版本3.x以上
**
安裝koa2
npm install koa2
mkdir koa2-demo && cd koa2-demo
1、初始化package.json
npm init
2、安裝koa2
npm install koa
hello world 代碼
const Koa = require('koa')
const app = new Koa()
app.use( async ( ctx ) => {
ctx.body = 'hello koa2'
})
app.listen(3000)
console.log('[demo] start-quick is starting at port 3000')
3、啓動Koa2的demo
由於koa2是基於async/await操作中間件,目前node.js 7.x的harmony模式下才能使用,所以啓動的時的腳本如下:
node index.js
接下來訪問http:localhost:3000,效果如下
kao2 async/await使用教程
async 是“異步”的簡寫,而 await 可以認爲是 async wait 的簡寫。所以應該很好理解 async 用於申明一個 function 是異步的,而 await 用於等待一個異步方法執行完成。
簡單理解:
async是讓方法變成異步。
await是等待異步方法執行完成。
詳細說明:
async是讓方法變成異步,在終端裏用node執行這段代碼,你會發現輸出了Promise { ‘Hello async’ },這時候會發現它返回的是Promise。
async function testAsync(){
return 'Hello async';
}
const result = testAsync();
console.log(result);
PS E:\study-project\koa-demo> node async.js
Promise { 'Hello async' }
await 在等待async方法執行完畢,其實await等待的只是一個表達式,這個表達式在官方文檔裏說的是Promise對象,但是它也可以接受普通值。 注意:await必須在async方法中纔可以使用因爲await訪問本身就會造成程序停止堵塞,所以必須在異步方法中纔可以使用。
koa2目錄結構分析
koa2源碼核心文件分析
├── lib
│ ├── application.js
│ ├── context.js
│ ├── request.js
│ └── response.js
└── package.json
這個就是 GitHub https://github.com/koajs/koa上開源的koa2源碼的源文件結構,核心代碼就是lib目錄下的四個文件
application.js 是整個koa2 的入口文件,封裝了context,request,response,以及最核心的中間件處理流程。
context.js 處理應用上下文,裏面直接封裝部分request.js和response.js的方法
request.js 處理http請求
response.js 處理http響應
正常情況下面我們不需要關注上面的文件,我們可以用koa應用生成器生成對應的目錄:
npm install koa-generator -g
koa koa_demo
Koa2生成器的使用:
目錄結構如下圖:
Koa2路由 以及 路由get傳值
在ko2a中,獲取GET請求數據源頭是koa中request對象中的query方法或querystring方法,query返回是格式化好的參數對象,querystring返回的是請求字符串,由於ctx對request的API有直接引用的方式,所以獲取GET請求數據有兩個途徑。
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
Koa2中 Cookie的使用
1、Koa中設置Cookie的值*
ctx.cookie.set(name,value,[options])*
通過 options 設置 cookie name 的 value 😗
*options 名稱 options 值*
*maxAge 一個數字表示從 Date.now() 得到的毫秒數*
*expires cookie 過期的 Date*
*path cookie 路徑, 默認是'/'*
*domain cookie 域名*
*secure 安全 cookie 默認false,設置成true表示只有 https可以訪問*
*httpOnly 是否只是服務器可訪問 cookie, 默認是 true*
*overwrite 一個布爾值,表示是否覆蓋以前設置的同名的 cookie (默認是 false). 如果是 true, 在同一個請求中設置相同名稱的所有 Cookie(不管路徑或域)是否在設置此Cookie 時從 Set-Cookie 標頭中過濾掉。*
2、Koa中獲取Cookie的值*
ctx.cookies.get('name');
3、Koa中設置中文Cookie*
console.log(new Buffer('hello, world!').toString('base64'));// 轉換成base64字符串:aGVsbG8sIHdvcmxkIQ==
console.log(new Buffer('aGVsbG8sIHdvcmxkIQ==', 'base64').toString());// 還原base64字符串:hello, world!
Koa2中Session koa-session的使用
npm install koa-session --save
const session = require('koa-session');
設置官方文檔提供的中間件
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 (默認default true)
httpOnly: true, //cookie是否只有服務器端可以訪問 httpOnly or not (default true)
signed: true, //簽名默認true
rolling: false, //在每次請求時強行設置cookie,這將重置cookie過期時間(默認:false)
renew: false, //(boolean) renew session when session is nearly expired,
};
app.use(session(CONFIG, app));
ctx.session.username = "張三"; // 設置值
ctx.session.username // 獲取值
Koa中Cookie和Session區別
1、cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session。
3、session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能
考慮到減輕服務器性能方面,應當使用COOKIE。
4、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
koa2 art-template高性能模板引擎的使用
Koa2中****常見模板引擎的性能對比
適用於 koa 的模板引擎選擇非常多,比如 jade、ejs、nunjucks、art-template等。
art-template 是一個簡約、超快的模板引擎。
它採用作用域預聲明的技術來優化模板渲染速度,從而獲得接近 JavaScript 極限的運行性能,並且同時支持 NodeJS 和瀏覽器。
art-template支持ejs的語法,也可以用自己的類似angular數據綁定的語法
官網:http://aui.github.io/art-template/
中文文檔: http://aui.github.io/art-template/zh-cn/docs/
視頻教程:https://www.itying.com/goods-800.html
npm install --save art-template
npm install --save koa-art-template
const Koa = require('koa');
const render = require('koa-art-template');
const app = new Koa();
render(app, {
root: path.join(__dirname, 'view'),
extname: '.art',
debug: process.env.NODE_ENV !== 'production'
});
app.use(async function (ctx) {
await ctx.render('user');
});
app.listen(8080);
art-template模板引擎語法
參考:http://aui.github.io/art-template/zh-cn/docs/syntax.html
綁定數據
{{list.name}}
綁定html數據
{{@list.h}}
條件
{{if num>20}}大於20{{else}}小於20{{/if}}
循環數據
{{each list.data}}
{{$index}}---{{$value}}
{{/each}}
引入模板
{{include 'public/footer.html'}}
Koa2模板引擎Ejs使用教程
EJS是一個JavaScript模板庫,用來從JSON數據中生成HTML字符串。Koa2框架中ejs可以把數據庫查詢的數據渲染到模板上面,實現一個動態網站。
Koa2 中使用ejs模板引擎的用法:
1、安裝 koa-views 和ejs
1.安裝koa-views
npm install --save koa-views
cnpm install --save koa-views
2.安裝ejs
npm install ejs --save
cnpm install ejs --save
2、引入koa-views配置中間件
const views = require('koa-views');
app.use(views('views', { map: {html: 'ejs' }}));
3、Koa中使用ejs:
router.get('/add',async (ctx)=>{
let title = 'hello koa2'
await ctx.render(index',{
title
})
})
**4、Ejs引入模板**
<%- include header.ejs %>
**5、Ejs綁定數據**
<%=h%>
**6、Ejs綁定html數據**
<%-h%>
**7、Ejs模板判斷語句**
<% if(true){ %>
true
<%} else{ %>
false
<%} %>
**8、Ejs模板中循環數據**
<%for(var i=0;i
<%=list[i] %>
<%}%>
Koa2上傳圖片模塊koa-multer的使用
Koa2中上傳圖片其實有很多模塊,下面給大家介紹的一個koa-multer上傳圖片的模塊。
koa-multer是一個 node.js 中間件,用於處理 multipart/form-data 類型的表單數據,它主要用於上傳文件。它是寫在 busboy 之上非常高效。
注意: Multer 不會處理任何非 multipart/form-data 類型的表單數據,意思就是我們要上傳圖片必須在form表單上面加 multipart/form-data
1.安裝Koa2 的koa-multer :
npm install --save multer
2.引入配置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 })
3.使用*koa-multer*
router.post('/doAdd', upload.single('face'), async (ctx, next) => {
ctx.body = {
filename: ctx.req.file.filename,//返回文件名
body:ctx.req.body
}
});
4.注意Form表單加上enctype="multipart/form-data"
使用*koa-multer 上傳多個圖片*
前臺表單:後臺:
router.post('/doAdd', upload.fields([{ name: 'pic', maxCount: 1 }, { name: 'aaa', maxCount: 1 }]),async (ctx)=>{
console.log(ctx.req.files);
})
kao2實現jsonp koa-jsonp模塊
koa-jsonp中間件
其中koa-jsonp是支持koa2的,使用方式也非常簡單,koa-jsonp的官方demo也很容易理解。
安裝
npm install --save koa-jsonp
簡單例子
const Koa = require('koa')
const jsonp = require('koa-jsonp')
const app = new Koa()
// 使用中間件
app.use(jsonp())
app.use( async ( ctx ) => {
let returnData = {
success: true,
data: {
text: 'this is a jsonp api',
time: new Date().getTime(),
}
}
// 直接輸出JSON支持jsonp
ctx.body = returnData
})
app.listen(3000, () => {
console.log('[demo] jsonp is starting at port 3000')
})
Koa2 分頁插件 jqPaginator_koa結合jquery分頁插件實現數據分頁
oa2 分頁插件 jqPaginator_koa結合jquery分頁插件實現數據分頁
一、數據庫分頁查詢數據的原理算法
規則:規定每頁20條數據的查詢方式
**
**
查詢第一頁(page=1):
db.表名.find().skip(0).limit(20)
查詢第二頁(page=2):
db.表名.find().skip(20).limit(20)
查詢第三頁(page=3):
db.表名.find().skip(40).limit(20)
規則:規定每頁8條數據的查詢方式
**
**
查詢第一頁(page=1):
db.表名.find().skip(0).limit(8)
查詢第二頁(page=2):
db.表名.find().skip(8).limit(8)
查詢第三頁(page=3):
db.表名.find().skip(16).limit(8)
查詢第四頁(page=4):
db.表名.find().skip(24).limit(8)
總結:分頁查詢的sql語句
db.表名.find().skip((page-1)*pageSize).limit(pageSize)
數據庫分頁方法封裝
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);
})
Koa2 結合jqPaginator實現分頁
對應路由:
router.get('/',async (ctx)=>{
var page=ctx.query.page ||1;
var pageSize=5;
//查詢總數量
var count= await DB.count('article',{});
var result=await DB.find('article',{},{},{
page:page,
pageSize:pageSize
});
await ctx.render('admin/article/index',{
list: result,
page:page,
totalPages:Math.ceil(count/pageSize)
});
})
**
對應模板中:**
定義一個div 注意 class爲bootstrap的分頁calss
<div id="page" class="pagination"></div>
然後複製下面代碼
<script src="{{__HOST__}}/admin/jqPaginator.js"></script>
<script>
$('#page').jqPaginator({
totalPages: {{totalPages}},
visiblePages: 8,
currentPage: {{page}},
onPageChange: function (num, type) {
console.log(num, type);
//
if(type=='change'){
location.href="{{__HOST__}}/admin/article?page="+num;
}
}
});
</script>
Koa2富文本編輯器ueditor的配置使用- Koa2 ueditor
一、Koa2 ueditor 以及Ueditor介紹
UEditor是由百度web前端研發部開發所見即所得富文本web編輯器,具有輕量,可定製,注重用戶體驗等特點,開源基於MIT協議,允許自由使用和修改代碼。
**官網:**http://ueditor.baidu.com/
**第三方sdk:**http://ueditor.baidu.com/website/thirdproject.html
二、Koa 中使用koa2-ueditor
1.安裝Koa2 的koa2-ueditor:
npm install koa2-ueditor --save
cnpm install koa2-ueditor --save
2.手動下載koa2-ueditor
**下載地址:**https://github.com/htzhanglong/koa2-ueditor
下載完成以後把官方例子中的example->public->ueditor複製到我們的項目裏面
3.對應的koa業務邏輯中配置koa2-ueditor 模塊 :
const ueditor = require('koa2-ueditor')
router.all('/editor/controller', ueditor(['public', {
"imageAllowFiles": [".png", ".jpg", ".jpeg"]
"imagePathFormat": "/upload/ueditor/image/{yyyy}{mm}{dd}/{filename}"
}]))
4.在模板中引入ueditor靜態文件
<script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.all.min.js"> </script>
<script type="text/javascript" charset="utf-8" src="/ueditor/lang/zh-cn/zh-cn.js"></script>
5、用到的文本框替換成下面代碼
<script id="editor" type="text/plain" style="width:800px;height:300px;"></script>
6、實例化編輯器
var ue = UE.getEditor('editor'); //注意和第五條的id對應起來
7、編輯器放入內容
var ueditor = UE.getEditor('editor');
ueditor.addListener("ready", function (){ /*注意*/
// editor準備好之後纔可以使用
ueditor.setContent(`{{@list.content}}`);
});
三、koa2-ueditor的一些配置
**
**
ueditor非常強大,可以自定義很多參數,找到ueditor裏面的ueditor.config.js進行配置
**配置上傳資源接口:**serverUrl *安全
**配置導航顯示內容:**toolbars
**配置自動長高:**autoHeightEnabled:false
koa2如何允許跨域_koa2跨域模塊koa2-cors
我們都知道 當域名、端口、協議有任意一個不一樣的時候就會存在跨域,那麼跨域如何解決呢,有好多種方式:
1、後臺允許跨域
2、jsonp
3、websocket
4、iframe
…等
用koa2寫了一個RESTful api,但是調試這個接口的時候,發現需要跨域,下面我們看看koa2-cors如何設置koa2後臺允許跨域。
npm install --save koa2-cors
引入 koa2-cors 並且配置中間件
var Koa = require('koa');
var cors = require('koa2-cors');
var app = new Koa();
app.use(cors());
koa2-cors官方地址:
https://github.com/zadzbw/koa2-cors
Koa中設置全局變量
Koa中設置全局變量可以通過 ctx.state.變量名 來設置 如下:
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.變量 設置的全局變量可以直接在模板用使用哦
如果在其他模塊中使用變量 直接通過 ctx.state.G.url來調用
ctx.state.G.url
如果在模板中使用直接通過 <%=url%> 來獲取
讓服務器主動給客戶端推送消息常見的做法有下面幾種方式。
**● 長輪詢:**客戶端每隔很短的時間,都會對服務器發出請求,查看是否有新的消息,只要輪詢速度足夠快,例如1秒,就能給人造成交互是實時進行的印象。這種做法是無奈之舉,實際上對服務器、客戶端雙方都造成了大量的性能浪費。
**● 長連接:**瀏覽器和服務器只需要要做一個握手的動作,在建立連接之後,雙方可以在任意時刻,相互推送信息。同時,服務器與客戶端之間交換的頭信息很小。
WebSocket是HTML5最新提出的規範,雖然主流瀏覽器都已經支持,但仍然可能有不兼容的情況,爲了兼容所有瀏覽器,給程序員提供一致的編程體驗,SocketIO將WebSocket、AJAX和其它的通信方式全部封裝成了統一的通信接口,也就是說,我們在使用SocketIO時,不用擔心兼容問題,底層會自動選用最佳的通信方式。因此說,WebSocket是SocketIO的一個子集。
Node.js從誕生之日起,就支持WebSocket協議。不過,從底層一步一步搭建一個Socket服務器很費勁。所以,有大神幫我們寫了一個庫Socket.IO。
Koa2中使用socket.io
1、在Koa2中安裝koa-socket模塊
cnpm i -S koa-socket
2、在Koa項目中引入koa-socket
const IO = require( 'koa-socket' )
3、實例化
const io = new IO()
4、調用 io.attach( app )
io.attach( app )
5、配置服務端
app._io.on( 'connection', socket => {
console.log('建立連接了');
socket.emit('serverEmit','我接收到增加購物車的事件了'); /*發給指定用戶*/
app._io.emit('serverEmit','我接收到增加購物車的事件了'); /*廣播*/
})
6、客戶端使用
Koa2中集成GraphQl實現 Server API 接口
GraphQL是一種新的API 的查詢語言,它提供了一種更高效、強大和靈活API 查詢。它彌補了RESTful API(字段冗餘,擴展性差、無法聚合api、無法定義數據類型、網絡請求次數多)等不足。
GraphQL的優點:
1、吸收了RESTful API的特性。
2、所見即所得
各種不同的前端框架和平臺可以指定自己需要的字段。查詢的返回結果就是輸入的查詢結構的精確映射
3、客戶端可以自定義Api聚合。
如果設計的數據結構是從屬的,直接就能在查詢語句中指定;即使數據結構是獨立的,也可以在查詢語句中指定上下文,只需要一次網絡請求,就能獲得資源和子資源的數據。
4、代碼即是文檔
GraphQL會把schema定義和相關的註釋生成可視化的文檔,從而使得代碼的變更,直接就反映到最新的文檔上,避免RESTful中手工維護可能會造成代碼、文檔不一致的問題。
5、參數類型強校驗
RESTful方案本身沒有對參數的類型做規定,往往都需要自行實現參數的校驗機制,以確保安全。
但GraphQL提供了強類型的schema機制,從而天然確保了參數類型的合法性。
下面我們看看Koa2中集成GraphQl實現 Server API 接口:
1、找到koa-graphql官方文檔
https://github.com/chentsulin/koa-graphql
2、安裝koa-graphql graphql koa-mount
npm install graphql koa-graphql koa-mount --save
3、引入koa-graphql配置中間件
const Koa = require('koa');
const mount = require('koa-mount');
const graphqlHTTP = require('koa-graphql');
const GraphQLSchema=require('./schema/default.js');
const app = new Koa();
app.use(mount('/graphql', graphqlHTTP({
schema: GraphQLSchema,
graphiql: true
})));
app.listen(4000)
4、定義GraphQLSchema
1、新建schema/default.js
2、定義Schema
const DB=require('../model/db.js');
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema,
GraphQLList
} = require('graphql');
//定義導航Schema類型
var GraphQLNav=new GraphQLObjectType({
name:'nav',
fields:{
title:{ type: GraphQLString },
url:{ type: GraphQLString },
sort:{ type: GraphQLInt },
status:{type:GraphQLInt},
add_time:{ type: GraphQLString }
}
})
//定義根
var Root = new GraphQLObjectType({
name: "RootQueryType",
fields: {
navList: {
type: GraphQLList(GraphQLNav),
async resolve(parent, args) {
var navList=await DB.find('nav',{});
console.log(navList)
return navList;
}
}
}
})
//增加數據
const MutationRoot = new GraphQLObjectType({
name: "Mutation",
fields: {
addNav: {
type: GraphQLNav,
args: {
title: { type: new GraphQLNonNull(GraphQLString) },
description:{ type: new GraphQLNonNull(GraphQLString) },
keywords:{ type: GraphQLString },
pid:{ type: GraphQLString},
add_time:{ type: GraphQLString},
status:{ type: GraphQLID}
},
async resolve(parent, args) {
var cateList=await DB.insert('nav',{title:args.title,description:args.description,keywords:args.keywords,pid:0,add_time:'',status:1});
console.log(cateList.ops[0]);
return cateList.ops[0];
}
}
}
})
module.exports = new GraphQLSchema({
query: QueryRoot,
mutation:MutationRoot
});
5、使用
GraphQl****增加數據
mutation{
addNav(title:“測試導航”,description:“描述”){
title
}
}
GraphQl查詢數據
{
articleList{
title,
cateList{
title,
description
}
}
}
koa2 301重定向,koa2 302重定向
koa2 中實現301重定向和302重定向 ,只需要通過ctx.status = 301; 然後通過ctx.redirect(’/cart’);進行跳轉就可以實現了。
koa2 301重定向代碼:
ctx.status = 301;
ctx.redirect(’/cart’); koa2
302重定向代碼:
ctx.status = 302;
ctx.redirect(’/cart’);
koa2 301重定向完整代碼:
router.get(’/’,async (ctx)=>{
ctx.status = 301;
ctx.redirect(’/cart’);
})
koa2 302重定向代碼:
router.get(’/’,async (ctx)=>{
ctx.status = 302;
ctx.redirect(’/cart’);
})
koa2 網站開啓gzip壓縮 ,koa-compress實現網頁gizp壓縮
koa2 或者nodejs網站開啓gzip壓縮後,可以加快網頁的加載速度。在Koa2中我們可以使用 koa-compress 開啓服務器Gzip壓縮功能。這樣服務器就會對網頁進行壓縮。讓我們可以更快速的打開網站。
koa2 網站開啓gzip壓縮只需要以下幾行代碼就能實現:
1、安裝****koa-compress中間件
cnpm install koa-compress --save
2、配置****koa-compress中間件
const koa = require('koa');
const compress = require('koa-compress');
const app = koa();
const options = { threshold: 2048 };
app.use(compress(options));
koa-compress github地址:
https://github.com/koajs/compress