koa框架和mongodb数据库,一小时快速入门和直击实战详细解读,建议收藏
Posted 贪吃ღ大魔王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了koa框架和mongodb数据库,一小时快速入门和直击实战详细解读,建议收藏相关的知识,希望对你有一定的参考价值。
koa
要求:nodejs的版本要高于7.6,因为 Node.js 7.6 版本 开始完全支持 async/await,所以才能完全支持我们的 Koa
npm i koa -S
使用
const Koa = require('koa');
const app = new Koa();
// ctx是上下文,其中包含了request和response
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
注意
:在koa中的app引用,只有use方法可以用来处理路由,没有请求动词方法,例如:app.get()这样会报错。
async/await和promise的使用
async用于修饰函数,放在函数声明的前面,将其后的函数的返回值封装成一个 Promise 对象
例:在终端中执行以下代码
async function testAsync(){
return 'Hello async';
};
const result = testAsync();
console.log(result); // Promise { 'Hello async' }
await必须在async方法中才可以使用,表示等待。等待的只是一个表达式,官方文档中说的是promise对象,其实他也可以接收普通的值。如果这个普通的值是一个函数的话,就等待这个函数的返回值。
例:
function getData() {
return 'This is data';
};
async function testAsync() {
return 'Hello async';
};
async function test() {
// await 返回普通值
const v1 = await getData();
console.log(v1);
// This is data
// await 返回promise对象
const v2 = await testAsync();
console.log(v2);
// Hello async
};
test();
路由
koa中要处理路由就需要使用路由模块来处理:
npm i koa-router -S
路由使用:
const Koa = require('koa')
const koaRouter = require('koa-router') // 导入路由
const router = new koaRouter() // 实例化路由
const app = new Koa()
router.get('/',(ctx,next)=>{
ctx.body = "hello"
})
router.get('/news',(ctx,next)=>{
ctx.body = '新闻页面'
})
app.use(router.routes()) // 启动路由 - 让路由生效
app.use(router.allowedMethods()) // 如果之前的没有设置响应头,配置此选项以后可以自动设置响应头 - 可加可不加(错误的时候会自动响应响应头)
app.listen(3000)
其中的导入路由和实例化路由可以合成一行:
const router = require('koa-router')()
路由处理中回调函数的next表示,让这个路由继续向下匹配处理。
路由执行顺序遵循洋葱圈模型:
例:
ar Koa = require('koa');
var router = require('koa-router')();
var app = new 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.匹配到了news这个路由');
ctx.body = '新闻页'
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
koa中的上下文ctx
koa中的ctx,包含了所有请求和所有的响应:
-
ctx.request - 代表服务器中的request对象
-
ctx.req - 代表服务器中的request对象 - ctx.request的简写
-
ctx.response - 代表服务器中的response对象
-
ctx.res - 代表服务器中的response对象 - ctx.reponse的简写
-
ctx.cookies.get(cookie的name) - 获取cookie
-
ctx.cookies.set(name, value, [options]) - 设置cookie
其中的option选项:
- maxAge:毫秒数 - 有效期 - 表示多长时间之后失效
- expires:有效期
- path:路径
- domain:指定子域名下可以访问
- secure:设置为true的时候,表示只有https才能访问
- httpOnly:true表示只能服务器端能访问,false表示客户端和服务器都能访问
请求信息
koa中默认将请求的信息ctx.request
上的内容绑定在了ctx上
- ctx.headers - 获取请求头信息
- ctx.header - 获取请求头信息 - ctx.headers的简写 - 可设置
- ctx.method - 获取请求方法 - 可设置
- ctx.url - 获取请求路径 - 带?的参数 - 可设置
- ctx.path - 获取请求路径 - 不带?的参数
- ctx.query - 获取?后的参数 - 结果为对象
- ctx.querystring - 获取?后的擦书 - 结果是字符串
- ctx.ip - 获取请求ip
响应信息
在koa中,将响应对象ctx.reponse
绑定在了ctx上:
- ctx.body - 响应主体 - 可赋值 - 可以是任意数据类型 - 参考官方文档
- ctx.status - 响应状态码 - 可赋值 - 必须是数字
- ctx.message - 响应状态描述 - 可赋值 - 设置状态描述 - 不能是中文
- ctx.redirect() - 跳转路由
有些响应必须是使用响应对象来操作:
-
response.set(fields) - 设置多个响应头
ctx.set({ 'Etag': '1234', 'Last-Modified': date });
-
response.append(field, value) - 追加一个响应头
ctx.append('Link', '<http://127.0.0.1/>');
-
response.set(field, value) - 设置一个响应头
ctx.set('Cache-Control', 'no-cache');
-
response.has(field) - 判断是否包含了某个响应头 - 返回布尔值
let bool = ctx.response.has('X-RateLimit-Limit');
-
response.get(field) - 获取响应头
const etag = ctx.response.get('ETag');
中间件
中间件可以理解为一个过滤器,让路由通过一个过滤器之后,进行或终止后续的处理。
中间件的作用:
执行任何代码
修改请求和响应对象
终结请求 - 响应循环
调用堆栈中的下一个中间件
正常情况下对于路由的处理,经过一个处理的回调函数之后,就停止了,如果我们希望他能继续执行下一个处理,可以调用next参数:
路由级别中间件
router.get('/goods',(ctx,next)=>{
ctx.body = '商品';
next() // 执行完这个处理回调之后继续向下执行 - 可以匹配下一个路由,进行进一步的处理
})
router.get('/goods',(ctx,next)=>{
ctx.body += "页面"
})
中间件执行结束后会执行next函数下的内容
这是路由级别中间件。
应用级别中间件
app.use(回调函数) // 可以匹配任意路由 - 需要向下进行的话就调用next
// 例
app.use(async (ctx,next)=>{
console.log(new Date()) // 每个路由都会打印时间
next()
})
应用级别中间件总是会先于路由级别中间件执行,无论放在前面或后面。
错误处理中间件
利用应用级别中间件会先执行的特性处理错误:
app.use(async (ctx,next)=>{
console.log('这是中间件');
await next()
// 当next向下执行后都没有匹配到合适的路由,就判断是否是404状态码来处理错误
if(ctx.status == 404){
ctx.body = "404页面,未找到资源"
}else{
console.log(ctx.url);
}
console.log(ctx.status);
})
第三方中间件
app.use(router.routes())
获取get请求主体
ctx.query // 获取到所有参数键值对组成的对象
ctx.querystring // 获取到所有参数的字符串形式
获取所有请求信息:
ctx.request
获取get参数也可以从请求信息中获取:
const req = ctx.request;
req.query // 对象
req.querystring // 字符串
动态路由参数:
router.get('/news/:id',(ctx,next)=>{
console.log(ctx.params);
ctx.body = '新闻页面'
})
// 请求地址:http://localhost:3000/news/123
// 获取到的值: { id: '123' }
获取post请求主体
原生nodejs获取:
router.post('/news',async ctx=>{
var str = '';
ctx.req.on('data',chunk=>{
str += chunk
})
crx.req.on('end',()=>{
console.log(str) // str就是获取到数据
})
ctx.body = "111"
})
使用第三方插件:
npm i koa-bodyparser
使用:
const bodyParser = require('koa-bodyparser')
router.post('/news',async ctx=>{
console.log(ctx.request.body);
ctx.body = "111"
})
app.use(bodyParser())
静态资源托管
依赖插件:koa-static
npm i koa-static
使用:
const staticMid = require('koa-static')
app.use(staticMid(__dirname + '静态资源目录')) // 请求的时候不需要加目录名 - 可以配置多个
静态资源托管可以配置多个,多个静态资源放在不同的文件夹时使用。
模板引擎
ejs
npm i koa-views # 让koa中能使用模板引擎
npm i ejs # 使用ejs
使用:
const views = require('koa-views')
app.use(views(模板存放目录,{
extension:"ejs"
}))
// 此时模板的后缀要ejs
// 或者
app.use(views(模板存放目录,{
map:{
html:"ejs"
}
}))
// 此时模板的后缀要html
// 渲染时 - 渲染是异步的,所以必须加await
await ctx.render(模板名称,{
数据
})
ejs语法:
<!-- 输出数据 -->
<%=变量名%>
<!-- 输出html内容并解析 -->
<%-变量名%>
<!-- 循环 -->
<%for(var i=0;i<list.length;i++){%>
<li><%=list[i]%></li>
<%}%>
<!-- 判断 -->
<%if(num > 18 ){%>
成年
<%}else{%>
未成年
<%}%>
<!-- 包含文件 -->
<%include 文件路径 %>
公共数据放在一个中间件中,然后每个响应处理都可以使用:
app.use(async (ctx,next)=>{
ctx.state = {
username:"张三"
}
await next()
})
其他响应处理就不用再次绑定数据,直接在模板中就能使用这个数据了 。
art-template
npm i art-template
npm i koa-art-template
使用:
const render = require('koa-art-template')
render(app,{
root:path.join(__dirname,'文件夹'), // 模板引擎存放地址
extname:".art" // 指定模板引擎后缀名
debug:process.env.NODE_ENV !== 'production'
})
其他使用跟ejs一样了
其他模块的使用
cookie注意事项
koa中不能直接设置中文的cookie,需要先将中文转为base64字符串设置,读取的时候,再将base64的字符串转换成中文:
// 中文转base64字符串
new Buffer(中文字符串).toString('base64')
// base64字符串转中文
new Buffer(base64字符串,'base64').toString()
session
npm i koa-session
使用:
const session = require('koa-session')
// 配置session的中间件
app.keys = ['some secret hurr']
const CONFIG = {
key: "koa:sess",
maxAge:86400000, // 有效期 - 毫秒数
overwrite:true, // 设置没什么效果
httpOnly:true, // true表示只有服务器端可以获取
signed:true, // 默认
rolling:false, // 每次访问重新设置
renew:true // 快到期的时候重新设置 - 一般会设置为true - true的时候会重新设置,只要操作就不会过期了
}
// 设置
ctx.session.键 = 值
// 获取
console.log(ctx.session.键)
上传
npm install koa-multer --save
使用:
// 引入koa-multer
const multer = require('koa-multer');
const router = require('koa-router')();
// 配置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 })
// 使用上传,upload.single()代表上传单个,参数为上传input的name值
router.post('/doAdd',
upload.single('input-name-value'), async (ctx, next) => {
ctx.body = {
// 返回文件名
filename: ctx.req.file.filename,
body: ctx.req.body
}
}
)
数据库操作
mysql
mongoDB
mongodb操作:依赖mongodb
npm i mongodb
使用:
const MongoClient = require('mongodb').MongoClient;
MongoClient.connect(dbUrl,(err,client)=>{
if(err){
console.log('连接错误!,错误为:'+err)
return;
}
let db = client.db(数据库名称)
let result = db.collection(表名).find({})
result.toArray((err,docs)=>{
console.log(docs)
})
})
封装:
新建config.js
const config = {
dbUrl:'mongodb://localhost:27017',
dbName:'koa'
}
module.exports = config
新建mongo.js
class Mongo{
static getInstance(){ // 多次实例化使用的同一个对象
if(!Mongo._intance) Mongo._instance = new Mongo()
return Mongo._instance
}
constructor(){
this.db = null
this.config = require('./config.js')
this.MongoClient = require('mongodb').MongoClient;
this.connect()
}
connect(){
return new Promise((resolve,reject)=>{
if(!this.db){
this.MongoClient.connect(this.config.dbUrl,(err,client)=>{
if(err){
reject(err)
}
this.db = client.db(this.config.dbName)
resolve(this.db)
})
return
}
resolve(this.db)
})
}
find(collectName,json={}){
return new Promise((resolve,reject)=>{
this.connect().then(db=>{
let result = db.collection(collectName).find(json)
result.以上是关于koa框架和mongodb数据库,一小时快速入门和直击实战详细解读,建议收藏的主要内容,如果未能解决你的问题,请参考以下文章
koa框架和mongodb数据库,一小时快速入门和直击实战详细解读,建议收藏