Koa后端小项目编程记录(二)get、post请求
一、前言
在上一章“项目搭建”:https://www.xinwei.ltd/article/132中,我们手动创建了一个ts的后端koa项目,实现了ts编译,并且引入了关键的koa库。
这一章我们来引入其他库,实现常见的post、get请求。
二、实现监听
koa作为后端框架,可以实现对端口port的监听,所有通过该端口的请求,都会被监听到,那么koa的监听如何实现呢,这里一个简单的举例:
app.ts
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
我们在app.ts中写入上面的代码,我们再来看一下package.json中的执行脚本:
package.json
...
"scripts": {
"dev": "ts-node app.ts",
"build": "tsc"
},
...
从这里的脚本命令,我们知道,当我们在根目录的终端中执行npm命令:
terminal
npm run dev
时,ts-node就会去编译app.ts文件,当编译时,实例化了koa,并且listen了3000端口,那么这个时候,程序并不会直接退出exit,而是会处于pending状态,监听着来自端口3000的消息。
上面的app.ts文件中,app.use方法是一个中间件写法,也就是说请求和响应都会经过这个中间件处理,而ctx.body被赋值'Hello World'这个字符串时,就表示任何经过3000端口的请求,都会收到'Hello World'这个字符串响应。
三、引入router库,实现一个简易get请求
在后端项目中,和前端的vue以及react都很类似,甚至在flutter中也有对应的路由概念router,哪怕在iOS的组件化之中,都是可以应用到router这样的概念。所以如果对这几个方向有过开发经验的同学,应该是可以理解router的概念的。
router这个概念在后端中也很普及,golang的项目同样也是有应用到的,所以有时候经验积累的足够多的时候,很多原理都是相通的,与诸君共勉。
我们讲正文吧,koa的router,其实就是请求的path,如何从端口监听到对应的path请求,并且对这个path请求做处理,也就是返回对应的接口响应。当你不使用router时,那么需要自己处理请求上下文中的path以及携带的请求参数。
这里我使用的是"@koa/router"这个npm包处理koa的路由请求,大家可以在npm包网站:https://www.npmjs.com/package/koa-router查看这个package。
我们在终端执行:
terminal
npm install @koa/router
并且安装对应的type支持包:
terminal
npm install --save-dev @types/koa__router
这样子,我们就可以做一下后端path路由,修改app.ts为:
app.ts
var Koa = require('koa');
var Router = require('koa-router');
var app = new Koa();
var router = new Router();
router.get('/', (ctx, next) => {
// 处理类似http://127.0.0.1:3000的get请求
ctx.body = "Hello World";
});
app
.use(router.routes())
.use(router.allowedMethods());
正如这个代码注释中提到的,重新运行npm run dev时,在浏览器中输入http://127.0.0.1:3000,就可以在网页上显示字符串Hello World,那么一个简单的get请求就实现了。
四、写一个post请求
我们在上面的步骤中写了一个简单的router的get请求,这里我们发散一下思维,封装一个用户登录信息模块。
在写登录信息模块之前,我们需要定义一下响应的类型结构,用来规范我们的响应数据格式。
- 定义响应码code的枚举:

error.ts
/**
* 接口返回的错误码
*/
enum NetErrorCode {
NotLogin = 401,
ParamError = 403,
NotFound = 404,
Success = 200,
}
export default NetErrorCode;
- 定义响应返回格式:

response.ts
import NetErrorCode from "./error";
/**
* 网络请求的返回
*/
export default class NetResponse<T> {
code: NetErrorCode;
msg?: string;
data?: T;
constructor(code: NetErrorCode, data: T, msg?: string) {
this.code = code;
this.data = data;
this.msg = msg;
}
}
这里使用了泛型,可以返回对应类型的数据data.
3. 创建一个router文件夹,用来存放对不同router的请求处理:
- 登录router:

router.ts
import NetErrorCode from "../dto/error";
import NetResponse from "../dto/response";
const Router = require("@koa/router");
const router = new Router();
router.get("/", (ctx: any, next: any) => {
console.log("请求了:", ctx);
next();
});
router.post("/login", (ctx: any, next: any) => {
console.log("登录信息是:", ctx.request.body);
console.log("登录信息是--headers:", ctx.request.headers);
ctx.body = new NetResponse<any>(NetErrorCode.Success, null, "");
});
export default router;
- 用户router:

user.ts
const Router = require("@koa/router");
const userRouter = new Router({
prefix: "/user",
});
userRouter.get("/profile", (ctx: any, next: any) => {
console.log("用户信息是--headers:", typeof next);
ctx.body = ctx.request.body;
});
export default userRouter;
这里解释一下,user router的实例化函数中,可以创建一个前缀,就像该例子中,我们定义了一个/user前缀,然后使用这个router实现一个get请求,那么这个user router就可以处理http://127.0.0.1:3000/user/profile这样的接口请求。
4. 修改app.ts如下:
app.ts
const Koa = require("koa");
import router from "./src/router/router";
import userRouter from "./src/router/user";
const app = new Koa();
// 根请求、login请求
app.use(router.routes()).use(router.allowedMethods());
// 用户模块
app.use(userRouter.routes()).use(userRouter.allowedMethods());
app.listen(3000);
- 本来到这一步,一切应该是可以正常接收get、post请求的,但。。。
当你通过postman这个软件,模拟一个请求:http://127.0.0.1:3000/login

postman的response中为空,vscode的终端输出结果是undefined,这是为何呢,原因是尽管router对koa的请求做了路由处理,但是没有对ctx做解析处理,所以我们从ctx.request.body中得到的是undefined.
那么我们开始下一步。
五、引入bodyparser库
这个库就是用来做body解析的,当然还有其他的一些库,比如koa-body,这里我们使用bodyparser库,地址是:https://www.npmjs.com/search?q=body-parser
执行终端命令:
terminal
$ npm i @koa/bodyparser --save
修改app.ts为:
app.ts
const Koa = require("koa");
const { bodyParser } = require("@koa/bodyparser");
import router from "./src/router/router";
import userRouter from "./src/router/user";
const app = new Koa();
app.use(bodyParser());
// 根请求、login请求
app.use(router.routes()).use(router.allowedMethods());
// 用户模块
app.use(userRouter.routes()).use(userRouter.allowedMethods());
app.listen(3000);
如代码所示,我们引入bodyParser,并且以中间件的方式进行使用,那么在对端口3000发送的任何请求,都会同步解析到ctx.request之中,这样子就能获取post携带的参数。
六、测试post携带参数请求


至此,post请求和get请求的案例就实现了。
本章到此结束,下一章继续。
暂无评论,快来发表第一条评论吧