koa框架入门(上)

1,243 阅读5分钟

简介

Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。

准备

首先,检查 Node 版本。

$ node -v
v8.0.0

Koa 必须使用 7.6 以上的版本。如果你的版本低于这个要求,就要先升级 Node。

准备好之后我们在本地建一个hell-world文件,然后通过npm install koa安装koa。 我们在项目根目录下创建一个app.js

// 1.引入koa
const Koa = require('koa')
// 2.创建koa实例
const app = new Koa()
// 3.创建一个中间件,所有的请求都会执行到这个中间件处理
// ctx是koa提供的上下文对象。(包含请求和对应的响应,通过加工这个对象就可以控制返回个用户的信息)
// ctx.request  请求 ctx.respond 响应
app.use(async (ctx) =>{

    // 设置响应体
    ctx.response.body = 'Hello World'
})
// 4.启动koa
app.listen(3000,()=>{
    console.log('请访问 http://localhost:3000');
})

我们在终端通过 node app.js启动一下项目,然后访问 http://localhost:3000 就可以看到打印的内容了。这样一个简单的应用程序就创建好了

koa中处理get请求

前面的步骤都是一样的,安装koa,然后导入创建koa实例,准备中间件。当我们打开页面之后在 http://localhost:3000/?username=zhangsan&age=18 拼接上参数之后,我们刷新页面,发现终端并没有反应,这个时候我们对中间件部分进行一个配置,通过ctx.request就可以接收到在url里面拼接的内容

image.png

当我们想拿到拼接的参数时可以通过ctx.request.query来获取。

image.png

// 1.引入koa
const Koa = require('koa')
// 2.创建koa实例
const app = new Koa()
// 3.创建一个中间件,所有的请求都会执行到这个中间件处理
// ctx是koa提供的上下文对象。(包含请求和对应的响应,通过加工这个对象就可以控制返回个用户的信息)
app.use(async (ctx) =>{

    // ctx.request  请求 ctx.response 响应
    // 通过query或者querystring来获取传过来的参数。
    // query是查询参数, 对象格式;querystring也是查询参数, 字符串格式。
    console.log(ctx.request.query);
    // 设置响应体
    ctx.response.body = 'Hello Wo rld'
})
// 4.启动koa
app.listen(3000,()=>{
    console.log('服务器启动成功');
})

koa处理post请求

获取post请求发送的请求题参数,相对较为繁琐,大致思路为:

  1. 监听node.js原生请求对象的data事件,从请求体中获取数据,并将所有数据拼合起来(因为如果请求体中携带的数据量比较大,就会分几次来触发data事件,逐步获取)
  2. 监听node.js原生请求对象的end事件,获知请求体数据被完全获取
// 引入koa
const Koa = require('Koa')
// 创建koa实例
const app = new Koa()
// 中间件
app.use((ctx)=>{
// ctx.req  ctx.res 这个是原生nodejs的
// ctx.request   ctx.response 这个是koa内置的
let paramsStr = ''

// 监听原生node.js request对象的 data事件
// 每次有数据过来,都会触发一次data,数据量大一次请求会触发多次data事件
ctx.req.on('data',(data)=>{
    paramsStr += data

})

//监听原生nodejs request对象的end事件
// 一旦请求所有的数据接收完成就会触发end事件
ctx.req.on('end',()=>{
    console.log(paramsStr,'结束');

})
})

app.listen(3000,()=>{
    console.log('启动成功');
})

之后当我们以同样的方式在浏览器输入http://localhost:3000的时候会发现页面提示 Not found,因为只有get请求可以通过这种方式,如果是post请求的话我们可以通过postman来进行测试。其中针对post请求返回的参数我们还可以通过URLSearchParams对其进行处理,比如

ctx.req.on('end',()=>{
    console.log(paramsStr,'结束');
    // { 'username' => 'zs', 'age' => '25' }
    // params.get(key)传入username就可以得到zs,传入age就可以得到18
    // params.has(key)是根据键来判断是否存在
    // params.keys()获取到所有键 
    const params = new URLSearchParams(paramsStr)
    console.log(params,'params=====>');
    console.log(params.get('age'));
    console.log(params.has('age'));
    console.log(params.keys());
})
})

响应一个页面

我们引入nodejs中的fs读文件模块,用来读取html页面。

// 响应页面
const Koa = require('Koa')
const fs = require('fs')
const path = require('path')
const { join } = require('path')
const app = new Koa()

app.use((ctx)=>{
    // __dirname找当前文件的绝对路径
    fs.readFile(join(__dirname,'test.html'),(err,data)=>{
        if(err){
            return console.log(err);
        }
        //  读取的数据是buffer格式的,需要用toString转换格式
        console.log();
        ctx.response.body = `data.toString()`

    })


})

app.listen(8000,()=>{
console.log('success!!');
})

但是这个时候我们会发现在浏览器打开的时候会提示Not Found,这是因为在读文件这个流程结束之前就已经执行了ctx.response.body = data.toString()这个操作,所以我们如果想要成功读取到html文件,我们需要把它阻塞,这里我们对函数进行一下封装:

// 响应页面
const Koa = require('Koa')
const fs = require('fs')
const path = require('path')
const { join, resolve } = require('path')
const { rejects } = require('assert')
const app = new Koa()

// 封装一读取html的函数 return 一个promise对象
function getHtmlFile(filePath) {
    return new Promise((resolve,reject)=>{

        // __dirname找当前文件的绝对路径
        fs.readFile(join(__dirname,filePath),(err,data)=>{
            if(err){
                return reject(err);
            }
            //  读取的数据是buffer格式的,需要用toString转换格式
            resolve(data.toString())
            // ctx.response.body = await 读取文件的 内容
    
        })
    })
} 
app.use(async ctx=>{
    ctx.body = await getHtmlFile('./test.html') //这里通过await对他进行阻塞
})

app.listen(8000,()=>{
console.log('success!!');
})

koa中处理静态资源

基本上和读取html页面一样,引入fs然后封装一个函数,不过需要注意的是,读取图片的时候要设置响应头!

// 响应页面
const Koa = require('Koa')
const fs = require('fs')
const path = require('path')
const { join, resolve } = require('path')
const { rejects } = require('assert')
const app = new Koa()

// 封装一个读取静态资源图片的函数
function getImageFile(filePath){
    return new Promise((resolve,reject)=>{
        fs.readFile(join(__dirname,filePath),(err,data)=>{
            if(err){
                return reject(err)
            }
            // 这里要保持buffer数据格式 
            resolve(data)
        })
        

    })
}
app.use(async ctx=>{
    // 重要:需要特别设置静态资源文件(图片)的content-type 响应头
    // 否则在浏览器中只会下载文件
    ctx.set('Content-type','image/png')
    ctx.body = await getImageFile('./koa.png')
})

app.listen(8000,()=>{
console.log('success!!');
})