稀土掘金技术社区 02月08日
从原生Node.js到Koa:Web服务的逆袭
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了Koa,一个由Express团队开发的轻量级Node.js框架。文章首先回顾了原生Node.js的Web服务开发方式,指出其在处理大量接口时存在的代码维护问题。随后,详细讲解了Koa的基本语法、中间件机制、路由定义以及如何处理GET和POST请求参数。最后,通过“洋葱模型”的比喻,生动地解释了Koa中间件的执行顺序,展示了Koa在构建高效、可维护的Web应用方面的优势。Koa以其简洁的设计和强大的功能,成为现代Node.js Web开发的理想选择。

🚀 Koa是一个由Express团队开发的轻量级Node.js框架,旨在简化Web应用开发,通过中间件机制优雅地处理请求,避免原生Node.js中大量的if-else语句。

⚙️ Koa的核心概念是中间件,通过`app.use()`加载,每个中间件接收`ctx`(包含request和response对象)和`next`(用于调用下一个中间件)作为参数。中间件的执行顺序呈现“洋葱模型”,先依次执行next()之前的代码,再逆序执行next()之后的代码。

🛣️ Koa通过`@koa/router`模块实现路由定义,可以方便地为不同的HTTP方法和路径绑定处理函数。通过`ctx.query`获取GET请求的参数,通过`@koa/bodyparser`中间件解析POST请求的参数,并通过`ctx.request.body`获取POST请求体中的数据。

✨ Koa可以灵活地处理不同类型的响应,通过`ctx.response.type`设置响应类型,例如`text`或`html`,并通过`ctx.body`设置响应体的内容,可以是字符串、HTML代码,甚至是读取文件流。

原创 六个点 2025-02-07 08:31 重庆

点击关注公众号,“技术干货” 及时达!

今天让我们来认识一个由Express背后的团队开发且非常轻量级的node.js框架 koa,再聊它之前我们先来看看原生的node开发。

原生node开发

我们先用原生node启动一个web服务;

 const http = require('http')
http.createServer((req, res) => { //req(请求体)和res(响应体) console.log(req.headers) }).listen(3000, () => { console.log('server is running'); })

其中「req是请求体,res响应体」

然后使用HTTP模块创建的基本服务器,且在接收到请求后打印出请求头的信息,并在本地主机的3000端口上监听连接。然后这里我们用postman当作前端朝这个端口发送一个GET请求。

然后看到控制台打印请求体中的请求头的信息。

然后我们可以使用res.end(xxx)将数据发送给前端。

   const http = require('http')
http.createServer((req, res) => { res.end('后端返回数据 hello world') }).listen(3000, () => { console.log('server is running'); })

这时再用postman朝地址发get请求,就可以拿到后端传过来的数据了,可以看到响应体中的数据如下。


浏览器是先拿到响应头,响应头中记录了响应时间,数据长度等信息。Content-Length指示响应体的长度,客户端可以根据该值确定数据传输是否已经完成,这也是响应头存在的意义,响应头还包含了其他重要信息,如Content-Type(指示数据的MIME类型)、Cache-Control(控制缓存行为)、Set-Cookie(设置cookies)等。

但如果想要请求'/home'路径下的数据呢?这就需要来个if判断请求体中的路径了。

   const http = require('http')
http.createServer((req, res) => { if (req.url === '/home') { res.end('首页的数据') } }).listen(3000, () => { console.log('server is running'); })

这样只有通过/home路径才可以拿到相应的数据,后端就是这样来制作不同的接口地址。

如果一个项目有很多个接口的话,就需要一直if else,这会导致代码难以维护和理解,就可以使用Koa这样的现代Node.js框架可以更好地组织和维护具有大量接口的项目。Koa提供了中间件机制,可以以更优雅的方式处理请求,避免了大量的if else语句。

koa

基本语法

koa并不是node自带的模块,所以需要npm来安装这个第三方库。

初始化项目,安装koa


npm init -y npm install koa

就可以看到koa源码:

然后将其引入到项目中使用


const Koa = require('koa') const app = new Koa() // 创建 koa 实例
<!---->
const Koa = require('koa') const app = new Koa()
const main = (ctx) => { // ctx 包含了 request 和 response 两个对象 console.log(ctx.url); // 打印请求的 url ctx.body = 'hello world' // 向前端返回的数据 }
app.use(main)
app.listen(3000, () => { console.log('服务器启动成功'); })

main 是一个中间件函数。在 Koa 中,中间件是一个函数,它接收一个 ctx(上下文)对象作为参数。「ctx 对象包含了请求(request)和响应(response)的信息」。想要向前端返回的数据就可以写在ctx.body里面。前端成功接收到数据。

当想传送的数据为<h2>Hello world</h2>,浏览器会自动将其当成html标签使用,如果就想将它当成字符串输出,就需要在响应头里面写上type属性里的内容,「ctx.response.type 设置响应类型,让浏览器知道该以什么方式解析响应体」,如下。

  const main = (ctx) => {      ctx.response.type = 'text'      ctx.body = '<h2>Hello world</h2>'    }

如果想要访问/home路径下时将一个html页面输出;

  const Koa = require('koa')    const fs = require('fs')  // 引入 fs
const app = new Koa()
const main = (ctx) => { if (ctx.url === '/home') { ctx.response.type = 'html' ctx.body = fs.readFileSync('./assets/template.html') // 读取html文件地址 // ctx.body = fs.createReadStream('./assets/template.html') // 十六进制,浏览器可直接将其解析成html } }
app.use(main)
app.listen(3000, () => { console.log('服务器启动成功'); })

定义接口

定义接口需要用到路由,然后在里面定义不同的路由来处理不同的接口,每个路由都关联一个HTTP方法和一个路径。

安装路由

  npm i @koa-router

引入使用

  const Router = require('@koa/router')    const router = new Router()    app.use(router.routes())  // 让路由生效

然后写一个首页的接口

  const Koa = require('koa')    const app = new Koa()    const Router = require('@koa/router')    const router = new Router()
// 首页的页面 router.get('/home', (ctx, next) => { ctx.body = { code: 200, msg: 'success', data: { name: '张三', age: 20, } } })
// 生效路由 app.use(router.routes())
app.listen(3000, () => { console.log('服务启动成功') })

回调函数里面的(ctx, next)参数是router.routes()里面的。

这时候前端访问/home接口。

当要请求需要传参数时,可以在 url 后面拼接?id=123,然后响应体通过ctx.query拿到传过来的参数。传多个值时可以使用&拼接。

   const Koa = require('koa')    const app = new Koa()    const Router = require('@koa/router')    const router = new Router()    // const { bodyParser } = require('@koa/bodyparser')
// app.use(bodyParser()) // 解析请求体
// 首页的接口 router.get('/home', (ctx, next) => { console.log(ctx.query); // { id: '123' } const { id } = ctx.query // 将传过来的对象解构出来
ctx.body = { code: 200, msg: 'success', data: { name: '张三', age: 20, id // 显示 } } })
// 生效路由 app.use(router.routes())
app.listen(3000, () => { console.log('服务启动成功') })

通过postman传值,如下;

再写一个登录接口,登录接口就要用到post了,但是 koa 的路由无法直接解析 post 传递的参数,需要使用 @koa/bodeparser 中间件来解析 post 请求的参数

使用npm i @koa/bodyparser安装。作用就是辅助koa解析post请求。

  const Koa = require('koa')    const app = new Koa()    const Router = require('@koa/router')    const router = new Router()
const { bodyParser } = require('@koa/bodyparser') app.use(bodyParser()) // 解析请求体
// 登录页面的接口 router.post('/login', (ctx) => { console.log(ctx.request.body); // { username: 'admin', password: 123 }
// 获取请求体中的用户名和密码 const { username, password } = ctx.request.body;
if (username === 'admin' && password === '123') { ctx.body = { code: 200, msg: '登录成功', user: ctx.request.body.username } } else { ctx.body = { code: 401, msg: '账号或密码错误' } } })
// 生效路由 app.use(router.routes())
app.listen(3000, () => { console.log('服务启动成功') })

post请求用ctx.request.body传入,而前面的get请求是通过?xxx传入。然后判断账号密码返回响应体里面的信息。然后我们通过postman传入账号密码比较。

后端拿到了前端postman传过来的参数。


洋葱模型

聊洋葱模型就是中间件的执行顺序的比喻。

koa里面的中间件就是一个函数,就是koa在执行过程中执行的函数,它接收两个参数:ctx(上下文对象)和 next(一个函数,用于调用下一个中间件)。中间件用于处理 HTTP 请求和响应。

看如下代码:

   const Koa = require('koa')    const app = new Koa()
const one = (ctx, next) => { console.log(1); next() // 直接调用下一个中间件 console.log(2); } const two = (ctx, next) => { console.log(3); next() console.log(4); } const three = (ctx, next) => { console.log(5); next() console.log(6); }
app.use(one) app.use(two) app.use(three)
app.listen(3000)

第一个中间件one执行到next()的时候就会直接调用下一个中间件two,当执行到最后一个中间件时,next()发现没有中间件就直接执行下一行,执行完后再往上一个中间件执行,就相当于一个递归,输出结果如下。

如果没有next()就只会执行第一个中间件,next()的存在就是为了可以人为地控制下一个中间件的执行,从而允许请求继续在中间件链中流动。

好了,关于koa就介绍到这里了,如果你觉得Koa这个小巧玲珑的框架让你心动不已,那就给它点个赞吧!毕竟,它可是个不折不扣的Web开发小能手,帮你轻松应对各种请求,让你的服务器跑得又快又稳。

点击关注公众号,“技术干货” 及时达!

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Koa Node.js Web框架 中间件 路由
相关文章