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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值