Node.js 是一个异步的世界,官方 API 支持的都是 callback 形式的异步编程模型,这带来许多问题,例如:1、callback 嵌套问题 2、异步函数中可能同步调用 callback 返回数据,带来不一致性。为了解决以上问题 Koa 出现了。
Web 框架。 使用 koa 编写 web 应用,可以免除重复繁琐的回调函数嵌套, 并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件, 它仅仅提供了一个轻量优雅的
函数库,使得编写 Web 应用变得得心应手。
阿里内部就在使用 Koa 框架,并在 Koa 基础上面做了一些扩展和封装。并且基于 koa 开发了一个
开源框架 egg
下载koa
npm install koa
js文件(基本框架):
//引入 Koa
const koa=require('koa');
const app=new koa();
//配置中间件 (可以先当做路由)
app.use( async (ctx)=>{
ctx.body='hello koa2'
})
//监听端口
app.listen(3000,()=>{
console.log('starting at port 3000');
});
路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET、POST 等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。
通俗的讲:路由就是根据不同的 URL 地址,加载不同的页面实现不同的功能。
Koa 中我们需要安装对应的 koa-router 路由模块来实现。
npm install koa-router
js文件使用:
const Koa = require('koa');
const router = require('koa-router')(); //注意:引入的方式
const app = new Koa();
//路由使用
router.get('/', async (ctx, next)=> {//ctx即上下文context,包含request和response
ctx.body="Hello koa";//ctx.body = res.writeHead+res.end
})
app.use(router.routes()).use(router.allowedMethods()) //作用:启动路由
app.listen(3000,()=>{
console.log('starting at port 3000');
});
app.use(router.allowedMethods());
作用: 这是官方文档的推荐用法,我们可以看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有路由中间件最后调用.此时根据 ctx.status 设置 response 响应头
const router = require(‘koa-router’)();
引入等同于以下两行
const router = require(‘koa-router’)
const router = new Router();
在 koa2 中 GET 传值通过 request 接收,但是接收的方法有两种:query 和 querystring。
query:返回的是格式化好的参数对象。
querystring:返回的是请求字符串。
router.get('/', function (ctx, next) {
ctx.body="Hello koa";
})
router.get('/newscontent,(ctx,next)=>{
let url =ctx.url;
//从上下文中直接获取
let ctx_query = ctx.query;//常用
let ctx_querystring = ctx.querystring;
//从 request 中获取 GET 请求,作用同上两行
//let request =ctx.request;
//let req_query = request.query;
//let req_querystring = request.querystring;
ctx.body={
url,
ctx_query,
ctx_querystring
}
});
//动态路由
router.get('/news/:aid', async (ctx, next) => {
//ctx.params 获取动态路由的传值,可以传入多个参
ctx.body = ctx.params //{"aid":"123"}
})
//动态路由可以传入多个参
router.get('/news/:aid/:cid', async (ctx, next) => {
ctx.body = ctx.params //{"aid":"123","cid":"222"}
})
**通俗的讲:**中间件就是匹配路由之前或者匹配路由完成做的一系列的操作,我们就可以把它叫做中间件。
在 express 中间件(Middleware)是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处理请求-响应循环流程中的中间件,一般被命名为 next 的变量。在 Koa 中间件和 express 有点类似。
中间件的功能包括:
执行任何代码。
修改请求和响应对象。
终结请求-响应循环。
调用堆栈中的下一个中间件。
如果我的 get、post 回调函数中,没有 next 参数,那么就匹配上第一个路由,就不会往下匹配了。如果想往下匹配的话,那么需要写 awit next()
几种中间件:应用级中间件、路由级中间件、错误处理中间件、第三方中间件
应用级中间件
app.use(async (ctx,next)=>{
console.log(new Date());
await next();//当前路由匹配完成以后继续向下匹配
})
router.get('/',async (ctx, next) => {
ctx.body="Hello koa";
})
router.get('/news',async (ctx, next) => {
ctx.body="新闻页面"
});
路由中间件
router.get('/', async(ctx, next)=>{
console.log(1)
next()
})
router.get('/', function (ctx) {
ctx.body="Hello koa";
})
错误处理中间件
app.use(async (ctx,next)=> {
//next之前最先运行
next();
//next之后最后运行
if(ctx.status==404){
ctx.status = 404;
ctx.body="这是一个 404 页面"
}
});
第三方中间件
const static = require('koa-static');
const staticPath = './static';
app.use(static(
path.join( __dirname, staticPath)
))
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
Koa 选择了洋葱圈模型。
原生 Nodejs 在Koa中获取 post 提交数据
function parsePostData(ctx){
return new Promise((resolve,reject)=>{
try{
let postdata="";
ctx.req.on('data',(data)=>{
postdata += data
})
ctx.req.on("end",function(){
resolve(postdata);
})
}catch(error){
reject(error);
}
});
}
1.安装 koa-bodyparser
npm install koa-bodyparser
2.使用
var Koa = require('koa');
var bodyParser = require('koa-bodyparser');//引入中间件
var app = new Koa();
app.use(bodyParser());//配置bodyParser的中间件
app.use(async ctx => {
ctx.body = ctx.request.body;//获取 post 提交的数据
});
1.安装 koa-static
npm install koa-static
2.引入配置中间件(可以多个),首先去static目录找 ,如果能找到返回对应的文件,找不到 next()
const static = require('koa-static');
//app.use(static(__dirname+'/static'));
app.use(static(
path.join( __dirname, 'public')
))
art-template 是一个简约、超快的模板引擎。
采用作用域预声明的技术来优化模板渲染速度,从而获得接近 JavaScript 极限的运行性能,并且同时支持 NodeJS 和浏览器。
下载
npm install art-template koa-art-template
使用
const render = require('koa-art-template');
render(app, {
root: path.join(__dirname, 'view'), //视图路径
extname: '.art', //后缀名,可以改成html
debug: process.env.NODE_ENV !== 'production' //是否开启调试模式
});
app.use(async function (ctx) {
//渲染index模板视图
await ctx.render('index',{
//传递数据
);
});
app.listen(8080);
语法参考:http://aui.github.io/art-template/zh-cn/docs/index.html
安装 koa-views 和 ejs
npm install koa-views ejs
引入 koa-views 配置中间件
const views = require('koa-views');
app.use(views('views', { map: {html: 'ejs' }}));//文件模板以html结尾,views是文件路径
//或
app.use(views('views', { extension: 'ejs' }))
Koa 中使用 ejs:
router.get('/add',async (ctx)=>{
let title = 'hello koa2'
await ctx.render(index',{
title
})
})
ejs语法
ejs 引入模板
<%- include header.ejs %>
ejs 绑定数据h
<%=h%>
ejs 绑定 html 数据h
<%-h%>
ejs 模板判断语句
<% if(true){ %>
true
<%} else{ %>
false
<%} %>
ejs 模板中循环数据
<%for(var i=0;i<%=list[i] %>
<%}%>
cookie 是存储于访问者的计算机中的变量。可以让我们用同一个浏览器访问同一个域
名的时候共享数据。
HTTP 是无状态协议。简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页
面,服务器无法认识到这是同一个浏览器在访问同一个网站。每一次的访问,都是没有任何
关系的。
1.Koa 中获取 Cookie 的值
ctx.cookies.get('name');
2.Koa 中设置 Cookie 的值,options是个对象
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表示这个cookie只有服务器端可以访问,false表示客户端(js),服务器端都可以访问
httpOnly 是否只是服务器可访问 cookie, 默认是 true
overwrite 一个布尔值,表示是否覆盖以前设置的同名 的 cookie (默认是 false). 如果是 true, 在同 一个请求中设置相同名称的所有 Cookie(不 管路径或域)是否在设置此 Cookie 时从 Set-Cookie 标头中过滤掉。
例子
ctx.cookies.set('userinfo','zhangsan',{
maxAge:60*1000*60
});
Koa 中设置中文 Cookie
// 转换成 base64 字符串:aGVsbG8sIHdvcmxkIQ==
console.log(new Buffer('张三').toString('base64'));
// 还原 base64 字符串:hello, world!
console.log(new Buffer('5byg5LiJ', 'base64').toString())
session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而
session 保存在服务器上。
工作流程
当浏览器访问服务器并发送第一次请求时,服务器端会创建一个 session 对象,生
成一个类似于 key,value 的键值对, 然后将 key(cookie)返回到浏览器(客户)端,浏览
器下次再访问时,携带 key(cookie),找到对应的 session(value)。 客户的信息都保存
在 session 中
koa-session 的使用
下载koa-session
npm install koa-session
引入
const session = require('koa-session');
设置官方文档提供的中间件
app.keys = ['some secret hurr'];/*cookie的签名*/
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: true, //快过期重新设置
};
app.use(session(CONFIG, app));
使用
设置值
ctx.session.username = "张三";
获取值
ctx.session.username
Cookie 和 Session 区别
1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗
考虑到安全应当使用 session。
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用 cookie 。
4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。