koa學習筆記

koa學習筆記:

文章來源:
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章