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数据库,一小时快速入门和直击实战详细解读,建议收藏

koa框架和mongodb数据库,一小时快速入门和直击实战详细解读,建议收藏

快速搭建可用于实战的koa2+mongodb框架

Koa快速入门教程

koa框架的快速入门与使用

快速入门koa2