首页 > 其他分享 >2020-2-26-koa框架使用

2020-2-26-koa框架使用

时间:2024-03-22 17:02:45浏览次数:16  
标签:26 koa app ctx 2020 var router require

快速上手、路由、动态路由、获取get值、中间间、koa-views使用、ejs小结、利用中间体配置公共变量、获取post数据、静态web服务、koa-art-template使用、cookies使用、session使用、mongodb数据库封装、路由模块化案例、快速创建koa项目koa-generator

快速上手

1安装

npm install koa --save

2使用

var koa=require('koa');//导入模块

var app=new koa()//创建对象

app.use(async(ctx)=>{
    ctx.body="hello"
})

app.listen(3000)

路由

1安装

npm install koa-roter --save

2使用路由后的代码

var koa=require('koa');
var router=require('koa-router')();//引入并实例化,不需要再new了

var app=new koa()

router.get('/',async(ctx)=>{//ctx,即contex,包含request,response等信息
    ctx.body='首页'//返回数据,相当于response.writeHead(),response.end('首页')
    //ctx.redirect('/')//跳转到'/'
})

app.use(router.routes())//配置路由
app.use(router.allowedMethods())

app.listen(3000)

动态路由

router.get('/newscontent/:id',async(ctx)=>{
    console.log(ctx.params)//{ id: '1' }
    ctx.body='新闻内容'
})

获取get传值

运行后,浏览器访问127.0.0.1:3000?name=zhang

router.get('/',async(ctx)=>{
    console.log(ctx.query)//{ name: 'zhang' }
    console.log(ctx.querystring)//name=zhang
    console.log(ctx.request.query)//{ name: 'zhang' }
    console.log(ctx.request.querystring)//name=zhang
    ctx.body='首页'
})

中间件

分为应用中间件、路由级中间件、错误处理中间件、第三方中间件

1应用中间件

//应用中间件
//1.无next参数
app.use(async (ctx)=>{
    ctx.body="你好"//无next参数将不再向下匹配路由
})

//2.有next参数
app.use(async (ctx,next)=>{
    ctx.body="你好"
    await next()//将会向下匹配路由,如果未匹配到则返回"你好"
})

2路由级中间件

router.get('/news',async(ctx,next)=>{
    console.log("第一次匹配")//执行
    ctx.body='第一次匹配结果'//后面同名路由如果有ctx.body,这里不执行,否则执行
    await next()
})

router.get('/news',async(ctx)=>{
    console.log("第二次匹配")//执行
    ctx.body='第二次匹配结果'
})

3错误处理中间件

app.use(async (ctx,next)=>{
    console.log("错误处理中间件")//一次请求中,次句将会被执行两次,类似洋葱模型
    await next()
    if(ctx.status==404){
        ctx.body="找不到页面"
    }else{
        console.log("无错误")
    }
})

4第三方中间件

其他中间件,需要用app.use进行配置


koa-views使用

1安装

npm install koa-views --save
npm install ejs --save

2代码

var views=require('koa-views')

//注意:配置语句必须放置再路由之前
//app.use(views('./views',{extension:'ejs'}))//html文件的后缀名必须是ejs
app.use(views('./views',{map:{html:'ejs'}}))//html文件的后缀名必须是html

router.get('/',async(ctx)=>{
    await ctx.render('hello',{})
})

ejs使用小结

{% raw %}
<!--引入-->
<%- include('header') -%>

<!--变量-->
<%=name%><!--name是传入的变量-->

<!--解析-->
<%-value%><!--解析value里的html代码-->

<!--循环-->
<%for(item of list){%><!--js写法-->
    <%=item%>
<%}%>
 
<!--判断-->
<%if(num>20){%><!--js写法-->
    <span>num大于20</span>	
<%}%>
{% endraw %}

利用中间体配置公共变量

app.use(async(ctx,next)=>{
    ctx.state.userinfo='zhang'
    await next()
})

所有html文件均可访问userinfo变量


获取post数据

1原生方式

1)getpostdata.js

var querystring=require('querystring');

function getpostdata(ctx){
    return new Promise((resolve,reject)=>{
        try{
            let str=''
            ctx.req.on('data',(chunk)=>{
                str+=chunk
            })
            ctx.req.on('end',()=>{
                str=querystring.parse(str)
                resolve(str)
            })
        }catch(err){
            reject(err)
        }
    })
}
module.exports=getpostdata

2)app.js核心代码

var getpostdata=require('./getpostdata')

router.post('/login',async(ctx)=>{
    var data=await getpostdata(ctx)
    console.log(data)//[Object: null prototype] { username: 'zhanghuan', password: '123' }
    ctx.response.body='<script>alert("success");history.back()</script>'
})

2插件方式

1)安装插件

npm install koa-bodyparser --save

2)核心代码

var bodyparser=require('koa-bodyparser')//导入

app.use(bodyparser())//配置,必须放在路由前面

router.post('/login',async(ctx)=>{
    console.log(ctx.request.body)//{ username: 'zhanghuan', password: '123' }
    ctx.response.body='<script>alert("success");history.back()</script>'
})

静态web服务

1安装

npm instaall koa-static --save

2核心代码

1)app.js

var static=require('koa-static')//导入
app.use(static('./static'))//配置

2)html文件中

<link rel="stylesheet" href="css/bootstrap.css">

art-template使用

1安装

npm install art-template --save
npm install koa-art-template --save

2核心代码

var render=require('koa-art-template')
var path=require('path')

render(app, {
    root: path.join(__dirname, 'views'),   // 视图的位置
    extname: '.ejs',  // 后缀名
    debug: process.env.NODE_ENV !== 'production'  //是否开启调试模式
});

router.get('/login',async(ctx)=>{
    await ctx.render('login',{'title':'title'})
})

3语法

{% raw %}
<!--引入-->
<%- include('header') -%>
    
<!--变量-->
{{name}}

<!--变量-->
{{name}}
    
<!--变量解析为html-->
{{@html}}
    
<!--判断-->
{{if age>20}}
<p>age大于20</p>
{{else}}
<p>age小于等于20</p>
{{/if}}
   
<!--循环-->
<ul>
	{{each list}}
	<li>{{$index}}--{{$value}}</li>
	{{/each}}
</ul>
{% endraw %}

cookies的使用

1)设置

let options={
        maxAge:"1000*60",       //cookie有效时长,单位:毫秒数
        expires:"0000000000",      //过期时间,unix时间戳
        path:"/",         //cookie保存路径, 默认是'/,set时更改,get时同时修改,不然会保存不上,服务同时也获取不到
        domain:".xxx.com",       //cookie可用域名,“.”开头支持顶级域名下的所有子域名
        secure:"false",       //默认false,设置成true表示只有https可以访问
        httpOnly:"true",     //true,客户端不可读取
        overwrite:"true"    //一个布尔值,表示是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie(不管路径或域)是否在设置此Cookie 时从 Set-Cookie 标头中过滤掉。
    }
ctx.cookies.set('name','zhanghuan',options)

2)获取

var name=ctx.cookies.get('name')

3)解决cookie无法用中文的问题

//设置cookies
router.get('/setcookies',async(ctx)=>{
    var str='今晚打老虎'
    var buffer=new Buffer(str).toString('base64')
    ctx.cookies.set('name',buffer,{maxAge:1000*60*60,})
    ctx.body="this is setcookies"
})

//获取cookies
router.get('/getcookies',async(ctx)=>{
    var result=new Buffer(ctx.cookies.get('name'),'base64').toString()
    ctx.body="this is getcookies"
})

session使用

1安装

npm install koa-session --save

2使用

var session=require('koa-session')

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.keys = ['some secret hurr'];//缺少这一行会报错Error: .keys required for signed cookies
 app.use(session(CONFIG, app));

//设置session
router.get('/setsession',(ctx)=>{
    ctx.session.username='张欢'
    ctx.body='success'
})

//获取session
router.get('/getsession',(ctx)=>{
    console.log(ctx.session.username)
    ctx.body=`${ctx.session.username}`
})

mongodb数据库操作封装

1config.js

//配置文件
var app={
    dbUrl:'mongodb://localhost:27017',
    dbName:'db01'
}
module.exports=app

2db.js

//在此文件内封装数据库操作的类
var mongoclient=require('mongodb').MongoClient
var ObjectID = require('mongodb').ObjectID
var config=require('./config.js')

class Db{
    static getIncetance(){//开启单例模式
        if(!Db.incetance){
            Db.incetance=new Db()
        }
        return Db.incetance
    }
    constructor(){
        this.connect()
    }
    connect(){
        let _that=this
        return new Promise((resolve,reject)=>{
            if(!_that.dbClient){//解决重复连接问题
                mongoclient.connect(config.dbUrl,(err,client)=>{
                    if(err){
                        reject(err)
                        return
                    }else{
                        resolve(client.db(config.dbName))
                    }
                })
            }else{
                resolve(_that.dbClient)
            }
        })
    }
    find(collection,json={}){
        return new Promise(async(resolve,reject)=>{
            let db=await this.connect()
            let result=db.collection(collection).find(json)
            result.toArray((err,res)=>{
                if(err){
                    console.log(err)
                    reject(err)
                }else{
                    resolve(res)
                }  
            })
        })
    }
    update(collection,json1,json2){
        return new Promise(async(resolve,reject)=>{
            let db=await this.connect()
            db.collection(collection).updateOne(json1,{$set:json2},(err,data)=>{
                if(err){
                    console.log(err)
                    reject(err)
                }else{
                    resolve(data)
                }
            })
        })
    }
    delete(collection,json){
        return new Promise(async(resolve,reject)=>{
            let db=await this.connect()
            db.collection(collection).deleteOne(json,(err,data)=>{
                if(err){
                    console.log(err)
                    reject(err)
                }else{
                    resolve(data)
                }
            })
        })
    }
    insert(collection,json){
        return new Promise(async(resolve,reject)=>{
            let db=await this.connect()
            db.collection(collection).insertOne(json,(err,data)=>{
                if(err){
                    console.log(err)
                    reject(err)
                }else{
                    resolve(data)
                }
            })
        })
    }
    getObjectId(id){
        return new ObjectID(id)
    }
}

module.exports=Db.getIncetance()

3app.js

//封装的类的使用案例
var koa=require('koa')
var router=require('koa-router')()
var db=require('./db.js')

var app=new koa()

app.use(router.routes())//配置路由
app.use(router.allowedMethods())

router.get('/',async(ctx)=>{//查询
    let data=await db.find('user')
    //console.log(data)
    ctx.body=`共有${data.length}条数据`
})

router.get('/insert',async(ctx)=>{//新增
    let data=await db.insert('user',{'name':'王麻子','age':30,'sex':'male','job':'coder'})
    //console.log(data)
    ctx.body=`insert:${data}`
})

router.get('/delete',async(ctx)=>{//删除
    let id=await db.getObjectId('5e4a88fc9ca5885c8806b955')//传入字符串为该条记录的id,将其转换成对象后再进行数据库操作
    let data=await db.delete('user',{'_id':id})
    //console.log(data)
    ctx.body=`delete:${data}`
})

router.get('/update',async(ctx)=>{//更新
    let data=await db.update('user',{'name':'王麻子'},{'name':'王麻子11'})
    console.log(data)
    ctx.body=`update:${data}`
})

app.listen(3000)

路由模块化案例

实际开发中,各个模块需要进行分离

1分离思路

--package.json
--package-lock.json
--app.js//入口文件
--views//存放html模板文件
	--index.html
--static//存放静态文件
	--css
		--bootstrap.css
		--bootstrap.css.map
--routes//存放路由文件
	--index.js
	--admin.js
--node_modules
--module//存放自定义模块

2文件代码

1)app.js

var koa=require('koa')
var router=require('koa-router')()
var app=new koa()

//静态路由
var static=require('koa-static')
app.use(static('./static'))

//路由
//业务流程均在路由里
var router_index=require('./routes/index.js')/*前台*/
var router_admin=require('./routes/admin.js')/*后台*/
router.use('/',router_index)
router.use('/admin',router_admin)

//模板
//待渲染的html
var render=require('koa-art-template')
var path=require('path')
render(app,{
    root: path.join(__dirname, 'views'),   // 视图的位置
    extname: '.html',  // 后缀名
    debug: process.env.NODE_ENV !== 'production'  //是否开启调试模式
})
app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000)
//此文件是项目启动的入口文件

2)index.js

var router=require('koa-router')()

router.get('/',async(ctx)=>{
    ctx.render('index')
})

module.exports=router.routes()

3)admin.js

var router=require('koa-router')()

router.get('/',async(ctx)=>{
    ctx.body='这是admin管理页面首页'
})

module.exports=router.routes()

4)index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="/css/bootstrap.css">
</head>
<body>
    <h1>this is index</h1>
</body>
</html>

快速创建koa项目koa-generator

1全局安装

npm install koa-generator -g

2创建项目

koa koa-demo

3安装依赖

cd ko-demo
npm install

4启动项目

npm start

标签:26,koa,app,ctx,2020,var,router,require
From: https://www.cnblogs.com/sylvesterzhang/p/18089844

相关文章

  • 2020-2-20-nodejs基础知识
    vs插件安装、快速运行、url模块使用、自动重启工具supervisor、自定义模块、下载第三方包、fs模块、Async、Await的使用、文件里、简易静态服务器、事件驱动EventEmitter、模拟登陆简单版、模拟express封装、操作mongodb数据库VScode插件安装需要安装NodeSnippets插件才会有提......
  • 2020-3-7-webpack打包工具
    概述、快速使用、配置文件、webpack-dev-server、babel使用概述为优化页面发送多次的二次请求导致加载速度变慢和处理错综复杂的文件依赖关系,则需要将项目中涉及的多个文件进行合并并重新构建。wepack是一个基于node.js项目构建工具,其构建方式是基于项目构建。安装npmiwebp......
  • 2020-5-11-Mybatis
    框架和架构、MyBatis概述、入门、增删改查操作、dao实现类增删改查、引用外部配置文件、配置实体类别名、注册指定包内的dao接口、动态sql、一对多查询、多对多查询、延迟加载、mybatis缓存、注解开发框架和架构1框架软件开发的一套解决方案,不同框架解决不同问题。框架中封装很......
  • 2020-5-5-JAVAWEB
    测试、反射、注解、Mysql、JDBC、Tomcat、servlet、HTTP、EL表达式、JSTL、Filter过滤器、代理模式、监听器、Redis、Maven测试1黑白盒测试黑盒测试:不需要写代码,给输入值,看程序能否给出期望的输出值白盒测试:需要写代码,关注程序具体执行流程2测试步骤1)定义测试类包名:cn.itca......
  • 2020-5-23-Spring
    简介、耦合、控制反转、依赖注入、注解方式反转控制和依赖注入、Spring整合Junit、银行转账案例、代理、AOP面向切面编程、JDBCTemplate简介1核心内容IOC反向控制、AOP面向切面编程2优势方便解耦,简化编程AOP编程支持声明式事务支持方便程序的测试方便集成各种优秀的框架......
  • 2020-1-1-GIT使用经验汇总
    Git安装、创建版本库、同步操作、分支管理、查看版本记录、远程仓库相关操作安装sudoapt-getinstallgit设置用户名和邮箱gitconfig--globaluser.name"yourname"gitconfig--globaluser.email"[email protected]"创建版本库1.创建目录mkdirlearniggitcdlearn......
  • 2020-1-3-ekyll安装使用
    jekyll是一个博客工具,将markdown文件生成静态网页,具有较好的迁移性。安装依赖包RubyRubyGemsNodeJsPython安装完成后重启电脑配置gem镜像$gemsources--addhttps://gems.ruby-china.com/--removehttps://rubygems.org/$gemsources-l安装jeckyll-pagination$g......
  • 2020-1-9-js新特性第二部分
    实现map函数、嵌套函数和闭包、arguments对象、函数参数、关系操作符、遍历数组foreach方法、map对象与object对象的区别、promise对象、生成器实现Map函数传入处理函数和数组,返回值为将数组内的数按照函数规则处理后新生成的数组window.onload=function(){functio......
  • 2020-1-6-js新特性第一部分
    var、let、const的区别,对象被定义为常量不受保护,自执行函数注意事项,箭头函数特点,对象扩展运算和对象解构运算,label语句,for...in...和for...of...的区别var、let、const的区别varletconst作用域函数花括号内全局是否可重复声明可以不可以不可以声明后是......
  • H.264
    什么是H.264高度压缩数字视频编解码器标准。H.264的数据格式是怎样的?H.264是一种视频编码标准,定义了视频数据的压缩和编码方式,但没有规定特定的数据格式。然而,H.264编码生成的视频流通常会采用一种常见的容器格式来封装,以便存储和传输。常见的容器格式包括MP4AVIMKVMO......