koa简单用法总结

   对koa搭建后台管理系统做一些总结,使用的是腾讯云开发和对象存储作为数据库和存储地点。

1.首先要安装node,然后npm init初始化,目的是生成package.json文件,package.json将显示安装了哪些模块。

2.安装所需的模块,如下

cnpm install koa --save //koa框架
cnpm install koa-json --save//返回给前端的json对象
cnpm install koa-bodyparser --save//post提交的对象
cnpm install koa-router --save//路由
cnpm install koa2-cors --save//解决跨区
cnpm install nodemon --save//启动服务器端
cnpm install axios --save//Ajax请求模块
cnpm install jsonwebtoken --save //token
cnpm install basic-auth --save //解析前端在header中传来的token
cnpm install --save @koa/multer multer //静态资源上传:img,video,
cnpm install cos-nodejs-sdk-v5 --save /腾讯云cos
cnpm install moment --save  //时间模块
cnpm install e-commerce_price --save //价格补零

3.创建下列文件夹,config放公用的组件,如云开发所用的相关命令,网络请求,验证等,router放要写的接口文件

 4.云开发相关,云开发需要向腾讯云发送网络请求,因为数据都是存储在网络上,所以要用到axios

const axios = require('axios')
const qs = require('querystring')

// 拼接tokenurl地址
let param = qs.stringify({
	grant_type:'client_credential',
	appid:'wxe9ec3f2fffcc21',//填自己的
	secret:'7a798a540c25fae7e8a528a19144df'//填自己的
})

// 获取token的地址:必须要得到token才有权限操作云开发数据库
let url  ='https://api.weixin.qq.com/cgi-bin/token?' + param

// 云环境id
let env = 'cloud1-5g6gnk6kabc018f4'

// 数据库插入记录url
let Addurl = 'https://api.weixin.qq.com/tcb/databaseadd?access_token='

// 数据库查询记录url
let Tripurl = 'https://api.weixin.qq.com/tcb/databasequery?access_token='

// 数据库更新记录url
let Updateurl = 'https://api.weixin.qq.com/tcb/databaseupdate?access_token='

// 订阅消息
let Subscribe = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token='

// 小程序码接口
let Qrcode = 'https://api.weixin.qq.com/wxa/getwxacode?access_token='

class getToken{
	constructor() {}
	
	// 获取token
	async gettoken(){
		try{
			let token = await axios.get(url)
			if(token.status == 200){
				return token.data.access_token
			}else{
				throw '获取token错误'
				// 出现throw这个关键词,就会进入到catch里面,并且throw给得值会在catch的参数里
			}
		}catch(e){
			throw '错误1'
		}
	}
	
	//调用云开发http api接口
	async posteve(dataurl,query){
		try{
			let token = await this.gettoken()
			let data = await axios.post(dataurl+token, {env,query})
			if(data.data.errcode == 0){
				return data.data
			}else{
				throw '请求出错'
			}
		}catch(e){
			throw '错误2'
		}
	}
	
}

module.exports = {getToken,Addurl,Tripurl,Updateurl}

5.写接口,前端就是调用接口获得数据,接口分get和post,get主要用于获得数据,post用于前端提交数据给后端,比如注册等,一个get接口写法

const router = require('koa-router')()//实例化new路由
const {getToken,Addurl,Tripurl,Updateurl} = require('../config/database.js')

router.get('/getlunbo',async ctx=>{
	const query =`db.collection("heima-getlunbo").get()`//模板字符串,用于定义云数据库的异步操作
	const res= await new getToken().posteve(Tripurl,query)//云数据库的操作结果用变量接收
	ctx.body=res.data.map(item=>{return JSON.parse(item)})	//ctx.body就是返回给前端的数据,在数据库存储的是josn字符串,所以用map()函数统一通过JSON.parse()变成josn对象,前端才能使用
})






module.exports=router.routes()

一个post 接口,需要安装koa-bodyparsernpm插件,获取post请求参数;

const router = require('koa-router')()//实例化new路由
const {getToken,Addurl,Tripurl,Updateurl} = require('../config/database.js')
const moment = require('moment')
moment.locale('zh-cn')

router.post('/uploadgoods',ctx=>{
	const {title,zhaiyao,img_url,sell_price,market_price,stock_quantity}=ctx.request.body//前端提交数据用的字段,代表前端会提交那些数据
	let time = moment().utcOffset(8).format('YYYY-MM-DD HH:mm:ss')//utcOffset(8)设置为东八区
	let query = `db.collection('dishes-data').add({data:
	{
		category:'${category}',name:'${name}',unitprice:${unitprice},unit:'${unit}',
		image:${image},quantity:0,onsale:true,cid:'${value}',time:'${time}'
	}
	})`//'${}'代表字符串变量,如果是数组就不用''
	
})

module.exports=router.routes()

get带参数接口,分为query和params两种,query

const router = require('koa-router')()//实例化new路由
const {getToken,Addurl,Tripurl,Updateurl} = require('../config/database.js')

router.get('/getgoods',async ctx=>{
	const {page} = ctx.query// /getgoods/?page=1
	const sk = page * 10
	const query = `db.collection('heima-getgoods').orderBy('add_time', 'desc').limit(10).skip(${sk}).get()`
	try{
		const res = await new getToken().posteve(Tripurl,query)
		const data = res.data.map(item=>{return JSON.parse(item)})//把字符串转换成对象
		const tatal = {tatal:res.pager.Total}//定义总数的对象
		const array = {...{result:data},...tatal}//对象组合
		ctx.body=array
		}
		catch(e){
			throw '错误500'
		}
})

module.exports=router.routes()

//.orderBy云开发排序

params

router.get('/package/:aid/:cid',async (ctx)=>{
    //获取动态路由的传值
    console.log(ctx.params);  //{ aid: '123', cid: '456' }
    ctx.body="详情";
})

.ctx.query获取get请求参数
   post提交的值在:ctx.request.body
   ctx.body是返回值
   
   路由中冒号后面的参数
   router.get("/banners/:id",(ctx,next)=>{
     const params = ctx.params;
     ctx.body = params;
   });
   访问 http://localhost:3000/mall/banners/1
   
   路由中问号后面的参数
   router.get("/banners",(ctx,next)=>{
     const query = ctx.query;
     ctx.body = query;
   });
   访问 http://localhost:3000/mall/banners?id=2
   
   路由中header带有的参数
   router.get("/banners",(ctx,next)=>{
     const header = ctx.header;
     ctx.body = header;
   });

6.在app.js的代码  

const Koa = require('koa')
const app = new Koa()
const json = require('koa-json')
const bodyParser = require('koa-bodyparser')
const router = require('koa-router')()//实例化new路由
const cors = require('koa2-cors')


app.use(cors())//app.use()注册中间件
app.use(json())
app.use(bodyParser())

//轮播图
const getlunbo = require('./router/getlunbo.js')
//获取商品列表
const getgoods = require('./router/getgoods.js')
//上传接口
const upload = require('./router/uploads.js')


//轮播图接口
router.use('/api',getlunbo)
router.use('/api',getgoods)
router.use('/api',upload)


/* 启动路由 */
app.use(router.routes()).use(router.allowedMethods())

// 自定义启动端口5000:不能跟其他程序的启动端口一样,否则造成端口冲突
app.listen(5000);
console.log('成功')

7.koa的中间件,个人理解为koa的功能模块,可以自定义中间件,格式为

async(ctx,next)=>{
   //方法体
}
await next()//关键是有next,这样才能执行下面的代码,在请求和返回之间做的事情就叫中间件

要在app.js中注册,注册后为全局中间件,所有路径都有效,不注册只对匹配的路径和方法生效

一个自定义中间价例子,局部中间件,可以写在路径后

const basicAuth = require('basic-auth')
const jwt = require('jsonwebtoken')
const security = require('./tokentime.js').security
const result = require('../config/handle.js')

class Auth{
	constructor() {}
	
	// 取值函数  set:存值函数
	get m(){//中间件
		return async(ctx,next)=>{
			const token = basicAuth(ctx.req)
			if(!token || !token.name){
				throw new result({errcode:'401',msg:'没有访问权限'},401)
			}
			try{
				var authcode = jwt.verify(token.name,security.secretkey)
			}catch(error){
				if(error.name == 'TokenExpiredError'){
					throw new result({errcode:'401',msg:'账号过期,请重新登陆'},401)
				}
				throw new result({errcode:'401',msg:'没有访问权限'},401)
			}
			ctx.auth = {
				uid: authcode.uid
			}
			await next()
		}
	}
}

module.exports = {Auth}
// 商家信息上传数据库
router.post('/uploadshop', new Auth().m, async ctx=>{
	const {id,name,address,logo} = ctx.request.body
	new shopinfor(ctx,name,address,logo).start()
	// 提交到数据库
	// 数组类型不需要这样:'${}'
	let query = `db.collection('shop-infor').add({data:{name:'${name}',address:'${address}',logo:${logo}}})`
	try{
		await new getToken().posteve(Addurl,query)
		new result(ctx,'提交成功').answer()
	}catch(e){
		new result(ctx,'提交失败,服务器发生错误',500).answer()
	}
})

中间件写在路径后,没有用app.use()注册

const router = require('koa-router')()//实例化new路由
const {getToken,Addurl,Tripurl,Updateurl} = require('../config/database.js')
const multer = require('@koa/multer')

/// 配置上传文件1.所在的目录和2.更改文件名
const storage = multer.diskStorage({//磁盘存储引擎方法
	destination:(req, file, cb)=> {//存储前端传来的文件
	    cb(null, 'upload/image')
	},
	filename:(req, file, cb)=> {
	   // 防止文件重名更改前缀 
	   // Date.now()时间戳6789045678889  
	   cb(null,file.fieldname+'-'+Date.now()+'.jpg')
	 }
})

const upload = multer({ storage})

router.post('/upload',upload.single('file'),async ctx=>{
	// console.log(ctx.file)//接收前端上传的静态资源文件:ctx.file
	try{
		const res = await cosfun(ctx.file.filename,ctx.file.path)
		ctx.body=res
		
	}catch(e){
		throw "上传错误"
	}
})

module.exports=router.routes()

@koa/multer文件上传的中间件

8.腾讯云模块上传

const COS = require('cos-nodejs-sdk-v5');//用腾讯云的模块进行上传

var cos = new COS({
   SecretId:'AKIDgBQO5VeX9UXKq53kAJBl58tNbR0II2',
   SecretKey:'vbz6xWprfCSR9ZiaATVFitnRnsgDTS',
   Protocol:'https:'
});

let Bucket = 'heima-1307717144'//存储桶
let Region = 'ap-guangzhou'//存储地址

let cosfun = function(filename,path){
	return new Promise((resolve,reject)=>{
		cos.uploadFile({
			Bucket,
			Region,
			Key:"heima/"+filename,              /* 必须 *///上传的文件,可以设定上传到哪个文件夹
			FilePath: path,  
		})
		.then(res=>{
			resolve(res.Location)
		})
		.catch(err=>{
			reject(err)
		})
	})
}

小程序舒尔特方格源代码_我爱的昵称为什么都存在的博客-CSDN博客小程序舒尔特方格源代码,使用uniapp编写https://blog.csdn.net/weixin_50501118/article/details/125075453 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值