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