koa2框架笔记
Node.js是一一个异步的世界,官方API支持的都是callback 形式的异步编程模型,这会带来许多问题例如:
- callback 嵌套问题
- 异步函数中可能同步调用callback返回数据,带来不一致性。
为了解决以上问题Koa出现了
Koa--基于Node.js 平台的下一代web开发框架
koa是由Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的Web框架。使用 koa编写web应用,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa不在内核方法中绑定任何中间件,它 仅仅提供了一个轻量优雅的函数库,使得编写Web应用变得得心应手。开发思路和express差不多,最大的特点就是可以避免异步嵌套。
koa2利用ES7的async/await特性,极大的解决了我们在做nodejs开发的时候异步给我们带来的烦恼。
koa学习网站
- 英语官网 http://koajs.com
- 中文官网 http://www.itying.com/koa
Koa2.x框架的安装使用
-
安装Node.js 8.x以上的版本
开发Koa2之前,Node.js 是确要求的,它要求Node.js版本高于V7.6。因为node.js 7.6版本开始完全支持async/await,所以才能完全你支持Koa2。
-
安装Koa:
安装Koa框架和我们以前安装其他模块是一-样的。
npm install koa --save
-save参数,表示自动修改package.json文件,自动添加依赖项。
安装koa2
// 初始化package.json
npm init --yes
// 安装koa2
npm install koa
hello world代码
//引入Koa
const koa=require(' koa ');
const app=new koa();
//配置中间件 (可以先当做路由)
app.use( async (ctx)=>{
ctx.body= 'hello koa2'
//监听端口
app. listen(3000);
Koa异步处理Async、Await 和Promise的使用(重点)
async是“异步”的简写,而await 可以认为是async wait的简写。所以应该很好理解async用于申明一个function 是异步的,而await 用于等待一个异步方法执行完成。
简单理解:
- async是让方法变成异步。
- await是等待异步方法执行完成。
详细说明:
async function testAsync(){
return 'Hello async';
}
const result = testAsync();
console.log(result);
//输出结果
Promise { 'Hello async' }
async是让方法变成异步,在终端里用node执行这段代码,你会发现输出了Promise {‘Helloasync’},这时候会发现它返回的是Promise。
await在等待async方法执行完毕执行
其实await等待的只是一个表达式,这个表达式在官方文档里说的是Promise对象,但是它也可以接受普通值。注意: await 必须在async方法中才可以使用因为await访问本身就会造成程序停止堵塞,所以必须在异步方法中才可以使用。
async/await同时使用
async 会将其后的函数(函数表达式或 Lambda)的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。
await阻塞的功能 把异步改成一个同步
asyne function getData() {
console.1og(2):
return '这是一个数据’;
}
async function test(){
console. log(1);
var d=await getData();
console. 1og(d);
console.1og(3);
}
test();
同步 异步 1/d/3/2
//1
//2
//这是一个数据
//3
async/await语法特点:
- 可以让异步逻辑用同步写法实现
- 最底层的await返回需要是Promise对象
- 可以通过多层async function的同步写法来代替传统的callback嵌套
koa路由、get 传值、动态路由
koa路由
路由(Routing)是由一个URI (或者叫路径)和一一个特定的HTTP方法(GET、POST等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。通俗的讲: 路由就是根据不同的URL地址,加载不同的页面实现不同的功能。
Koa中的路由和Express有所不同,在Express中直接引入Express就可以配置路由,但是在Koa中我们需要安装对应的koa-router路由模块来实现。
npm install koa-router --save
const Koa = require('koa');
const Router = require('koa-router');
//实例化
const app = new Koa();
const router=new Router();
//配置路由
//ctx 上下文 context req,res等信息都放在ctx里面
router.get('/', async (ctx)=> {
ctx.body="首页";//返回数据 原生里面的res.send()
})
router.get('/news, async(ctx)=>{
ctx.body= "这是一个新闻页面”
});
//启动路由
app.use(router.routes());
//可以配置也可以不配置 建议配置
app.use(router.allowedMethods());
//这是官方文档的推荐用法,我们可以看到router.allowedMethods()用在了路由匹配router.routes()之后,所以在当所有路由中间件最后调用。 此时根据ctx.status设置response响应头
app.listen(3000,()=>{
console.1og('starting at port 3000' ) ;
});
koa路由get传值
在koa2中GET传值通过request接收,但是接收的方法有两种:query和querystring
- query:返回的是格式化好的参数对象
- querystring:返回的是请求字符串
router.get( '/news', (ctx)=>{
let url=ctx.url;
//从request中获取GET请求
let request =ctx.request;
let req_query=request.query;
let req_querystring=request.querystring;
//从ctx中直接获取
let ctx_query = ctx.query; //{id:123,name:123} 获取的对象 推荐
let ctx_querystring = ctx.querystring;//id=123&name=123 获取的字符串
ctx.body={
url,
req_ query,
req_ querystring,
ctx_ query,
ctx_ querystring
}
});
POST请求参数获取原理
对于POST请求的处理,koa2没有封装获取参数的方法,需要通过解析上下文context中的原生node.js请求对象req,将POST表单数据解析成query string(例如:a=1&b=2&c=3),再将query string 解析成JSON格式(例如:{"a":"1", "b":"2", "c":"3"})
注意:
ctx.request是context经过封装的请求对象,ctx.req是context提供的node.js原生HTTP请求对象,同理ctx.response是context经过封装的响应对象,ctx.res是context提供的node.js原生HTTP请求对象。
获取Post请求的步骤:
- 解析上下文ctx中的原生nodex.js对象req。
- 将POST表单数据解析成query string-字符串. (例如:user=jspang&age=18)
- 将字符串转换成JSON格式。
// 解析上下文里node原生请求的POST参数
function parsePostData( ctx ) {
return new Promise((resolve, reject) => {
try {
let postdata = "";
ctx.req.addListener('data', (data) => {
postdata += data
})
ctx.req.addListener("end",function(){
let parseData = parseQueryStr( postdata )
resolve( parseData )
})
} catch ( err ) {
reject(err)
}
})
}
// 将POST请求参数字符串解析成JSON
function parseQueryStr( queryStr ) {
let queryData = {}
let queryStrList = queryStr.split('&')
console.log( queryStrList )
for ( let [ index, queryStr ] of queryStrList.entries() ) {
let itemList = queryStr.split('=')
queryData[ itemList[0] ] = decodeURIComponent(itemList[1])
}
return queryData
}
动态路由
router.get('/news/:id', async(ctx)=>{
//获取动态路由的传值
console.log(ctx.params)//{id:xxx}
ctx.body= "这是一个新闻页面”
});
中间件
通俗的讲: 中间件就是匹配路由之前或者匹配路由完成做的一系列的操作,我们就可以把它叫做中间件
在express中间件(Middleware) 是一个函数它可以访问请求对象(request object (req)),响应对象(response object(res))和web应用中处理请求-响应循环流程中的中间件,一般被命名为next的变量。在Koa中中间件和express有点类似
中间件的功能包括:
- 执行任何代码
- 修改请求和响应对象
- 终结请求-响应循环
- 调用堆栈中的下一一个中间件
如果get,post回调函数中,没有next参数,那么就匹配上第一个路由,就不会往下匹配了。如果想往下匹配的话,那么需要写next()
Koa应用可使用如下几种中间件:
- 应用级中间件
- 路由级中间件
- 错误处理中间件
- 第三方中间件
应用级中间件 匹配任何路由
app.use(async (ctx,next)=>{
//匹配路由之前打印日期
console.log(new Date());
await next(); //当前路由匹配完成以后继续向下匹配
})
路由级中间件
//匹配到news路由以后继续向下匹配路由
router.get('/news', async(ctx, next)=>{
console.log(1)
await next()
})
router.get('/news', function (ctx) {
ctx.body="Hello koa";
})
错误处理中间件
app.use(async (ctx,next)=> {
await next();
//如果页面找不到
if(ctx.status==404){
ctx.status = 404;
ctx.body="这是一个404页面"
}
});
Koa中间件的执行顺序
app.use(async (ctx,next)=> {
console.log('1.这是第一个中间件01')
await next();
console.log('5.匹配路由完成以后又会返回来执行中间件')
}
});
app.use(async (ctx,next)=> {
console.log('2.这是第一个中间件02')
await next();
console.log('4.匹配路由完成以后又会返回来执行中间件')
}
});
router.get('/news', async (ctx)=> {
console.log('3.匹配到了这个路由')
ctx.body="这是一个新闻";
})
结果
1、这是第一个中间件01
2、这是第二个中间件02
3、匹到了news这个路由
4、匹配路由完成以后又会返回来执行中间件
5、匹配路由完成以后又会返回来执行中间件
koa ejs模板引擎
ejs把nodejs后台的数据渲染到静态页面上
Koa中使用ejs 模板的使用
1.安装koa-views 和ejs
- 安装koa-views
npm install --save koa-views - 安装eis
npm install ejs --save
2.引入koa-views 配置第三方中间件
//第一种方式配置 模板后缀名为ejs
const views = require('koa views');
app.use(views(‘views’,{extension:'ejs'}));//应用ejs模板引擎
//第二种方式配置 模板后缀名为html
const views = require('koa views');
app.use(views(‘views’,{
map:{html:'ejs'}
}));
3.渲染对应的模板引擎
router.get('/add',async (ctx)=>{
let title = 'hello koa2'
await ctx.render(index',{
title:title
})
})
4.Ejs引入模板 引入外部公共文件
<%- include public/header.ejs %>
5.Ejs绑定数据
<%=h%>
6.Ejs绑定html的数据
let content="<h2>这是一个h2</h2>”
await ctx.render ('/news',{
content: content
})
<%-content%>
7.Ejs模板判断语句
<% if(true){ %>
true
<%} else{ %>
false
<%} %>
8.Ejs模板中循环数据
<ul >
<%for(var i=0;i<1ist. length;i++) {%>
<1i><%=1ist[i]%></1i>
<%}%>
</u1>
注意:我们需要在每一个路由的render里面都要這染一个公共的数据
公共的数据放在这个里面,这样的话在模板的任何地方都可以使用
//写一个中间件配置公共的信息
app. use (async (ctx,next)=> {
ctx.state.userinfo='张三';
await next();
})
koa 获取pos提交的数据
Koa中koa-bodyparser中间件的使用
1.安装koa-bodyparser
npm install --save koa-bodyparser
2.安装引入配置中间件
var Koa = require('koa');
var bodyParser = require('koa-bodyparser');
var app = new Koa();
app.use(bodyParser());
app.use(async ctx=> {
ctx.body = ctx.request. body;
});
3.通过ctx.request.body 获取post提交的数据
//接收post提交的数据
router.post('/doAdd',async (ctx)=>{
ctx.body=ctx.request.body;|
})
koa-static静态资源中间件
一、koa-static静态资源中间件的功能:
一个http请求访问web服务静态资源,一般响应结果有三种情况
- 访问文本,例如js,css,png,jpg,gif
- 访问静态目录
- 找不到资源,抛出404错误
koa-static主要是用于访问静态资源
二、Koa 中koa-static中间件的使用
1、安装 koa-static
npm install --save koa-static
2、引入配置中间件
const static = require('koa-static');
//http://localhost:3000/css/basic.css
//首先去static目录找,如果能找到返回对应的文件,找不到next()
//app.use(static(_dirname+'/static'));
app.use(static('./static'));
koa 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/
1.安装art-template 和 koa-art-template
npm install --save art-template
npm install --save koa-art-template
2.配置koa-art-template中间件:
const Koa = require('koa');
const render = require('koa-art-template');
const app = new Koa();
render(app, {
root: path.join(__dirname, 'views'),//视图的位置
extname: '.html',//后缀名
debug: process.env.NODE_ENV !== 'production'//是否开启调试模式 true/false
});
router.get('/',async (ctx) {
await ctx.render('index');
});
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'}}
Cookie的使用
一、COOKIE 简介
- cookie保存在浏览器客户端
- 同一个浏览器访问同一个域共享数据
- 保存用户信息
- 浏览器历史记录
- 猜你喜欢的功能
- 10天免登陆
- 多个页面之间的数据传递
- cookie实现购物车功能
二、Koa2中 Cookie的使用
1、Koa中设置Cookie的值
ctx.cookies.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 标头中过滤掉。 |
path:’/news', /*配置可以访问的页面*/
domain:'.baidu.com’ //正常情况不要设置默认就是当前域下面的所有页面都可以访问
//
a. baidu. com
b. baidu. com共享cookie的数据I
2、Koa中获取Cookie的值
ctx.cookies.get('name');
三、Koa中设置中文Cookie
console.log(new Buffer('hello, world!').toStr('base64');
// 转换成base64字符串:aGVsbG8sIHdvcmxkIQ==
console.log(new Buffer('aGVsbG8sIHdvcmxkIQ==', 'base64').toString());
// 还原base64字符串:hello, world!
Koa2中 Cookie的使用教程下载地址:https://pan.baidu.com/s/1KNaA97kGwNhavch5rP_G7w
上面地址失效请访问:https://www.itying.com/goods-800.html
Koa Session的使用
一、Koa-Session简单介绍
session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而session保存在服务器上。
二、Session的工作流程
当浏览器访问服务器并发送第一次请求时,服务器端会创建一个session对象,生成一个类似于key,value的键值对, 然后将key(cookie)返回到浏览器(客户)端,浏览器下次再访问时,携带key(cookie),找到对应的session(value)。 客户的信息都保存在session中
三、koa-session的使用:
- 安装 koa-session
npm install koa-session --save
- 引入express-session
const session = require('koa-session');
- 设置官方文档提供的中间件
app.keys = ['some secret hurr'];//cookie的签名
const CONFIG = {
key: 'koa:sess', //cookie key (默认 is koa:sess)
maxAge: 86400000, // cookie的过期时间 默认一天
overwrite: true, //是否可以overwrite 没有效果 (默认default true)
httpOnly: true, //cookie是否只有服务器端可以访问 (default true)
signed: true, //签名默认true
rolling: false, //在每次请求时强行设置session,这将重置session过期时间(默认:false)
renew: true, //当它快过期的时候重新设置 需要设置 true
};
app.use(session(CONFIG, app));
-
使用
设置值 ctx.session.username = "张三";
获取值 ctx.session.username
四、Koa中Cookie和Session区别
cookie数据存放在客户的浏览器上,session数据放在服务器上。
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
MongoDB Compass Community可视化工具 (官方提供)
MongoDB Compass是MongoDB官网提供的一个集创建数据库、管理集合和文档、
运行临时查询、评估和优化查询、性能图表、构建地理查询等功能为一体的MongoDB
可视化管理工具。
下载最新的mongodb安装完成后会自动安装mongodb可视化工具
https://www.mongodb.com/download-center?imp=nav#community单独下载mongodb可视化工具
https://www.mongodb.com/products/compass
https://www.mongodb.com/download-center?jimp=nav#compass
一、索引基础
索引是对数据库表中一列或多列的值进行排序的一一种结构,可以让我们查询数据库变得
更快。MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括- -些基本的查
询优化技巧。
下面是创建索引的命令 :
db.user.ensureIndex({"username":1})
获取当前集合的索引:
db.user.getIndexes()
删除索引的命令是:
db.user.dropIndex( {"username":1})
封装mongodb DB库之前的一些准备工作 es6 class类静态方法以及单例模式
es6 class类
//定义Person类
class Person {
constructor (name, age) { /*类的构造函数,实例化的时候执行,new的时候执行*/
this._name=name;
this._age=age;
}
getName() {
alert(this._ name);
}
setName (name) {
this. name-name
}
}
var p=new Person('张三1',' 20' );//实例化
es6 里面的继承
class Web extends Person{ //extends关键字继承了Person
constructor (name,age,sex) {
super(name, age); // super 实例化子类的时候把子类的数据传给父类
this.sex=sex;
}
print() {
console.log(this.sex);
}
}
es6 里面的静态方法
class Person {
constructor (name) {
this._ name=name; /*属 性*/
}
run(){ /*实例方法*/
console.log(this._name);
}
static work(){ /*静态方法*/
console.log('这是一个静态方法');
}
}
var p=new Person('张三’);
r.run();
Person.work(); //直接调用静态方法
es6 里面的单例
无论实例化多少次 构造函数只执行一次
优点:有利于提高性能
class Db {
constructor:(){
console.log("实例化会触发构造函数’);
this.connect();
}
connect() {
console. log('连接数据库’);
}
find({
console. log('查询数据库' );
}
static getInstance(){ //单例 判断有没有实例,有直接返回
if(!DB.instance){
Db.instance=new new Db();
}
return Db.instance
}
}
var db=new Db()
var mydb1=Db.getInstance()
var mydb2=Db.getInstance()
var mydb2=Db.getInstance()
//调用静态方法只实例化一次
封装Koa 操作Mongodb数据库的DB类库
目标
基于官方的node- mongodb-native驱动,封装一个更小、更快、更灵活的DB模块,让我们用nodejs操作Mongodb数据库更方便、更灵活。
-
安装mongodb
cnpm install mongodb --save
引入mongodb下面的MongoClient
var MongoClient = require('mongodb').MongoClient;
- 定义数据库连接的地址 以及配置数据库
定义数据库连接的地址
var dburl = 'mongodb://localhost:27017/';
定义数据库的名称
var dbName = 'koa'
-
nodejs连接数据库
MongoClient.connect(url,function(err,client){
const db = client.db(dbName); 获取数据库db对象
})
操作数据库
MongoClient.connect(url,function(err,db){
if(err){
console. log(err);
return;
}
//添加数据
db.collection('user').insertOne({"name":"张三"},
function(err,result){
if(!err){
console. log(‘添加成功’);
}
db.close(); //关闭连接
})
//查询数据
var resul t=db.collection('user').find({});
result.toArray((err, result)=>{
console.log(result) ;
})
})
Koa应用生成器以及Koa路由模块化
一、koa应用生成器
通过应用koa脚手架生成工具可以快速创建一个基于koa2的应用的骨架,实现路由模块化
-
全局安装
npm install koa-generator -g
-
创建项目
koa koa_ demo
-
安装依赖
cd koa_ demo
npm install -
启动项目
npm start
Koa2生成器的使用:
https://www.itying.com/koa/start-generator.html
目录结构如下图: