Skip to main content

Koa2 搭建 Node.js 项目

Koa 是 Express 团队打造的新 web server 框架,与 Express 的区别在于:

  • Koa 不涉及路由及其他中间件的捆绑,体积比 Express 小;
  • Koa 支持 async / await 写法,在异步处理上比 Express 的 Promise 回调写法更友好;
  • Koa 使用洋葱圈模型的函数调用栈执行中间件,先调用的后执行完,而 Express 使用先进先出的任务队列执行中间件,先调用的先执行完。

一、Koa 项目搭建

1、全局安装脚手架

npm i koa-generator -g

2、新建 Koa 项目

# 新建 Koa 项目
koa2 new-project

# 装包和启动
npm i & npm start

3、项目启动优化

Koa 项目自带 nodemon 和 dev 等启动命令,不需要额外安装 nodemon 监测文件变化,自动重启 node。

与前面手动搭建 Node.js 项目同理,可以安装 cross-env 跨平台运行脚本,设置环境变量,兼容 mac、linux 和 windows;

npm i cross-env --save-dev

接着在 package.json 中修改:

{
"scripts": {
"dev": "./node_modules/.bin/nodemon bin/www",
"dev": "cross-env NODE_ENV=dev ./node_modules/.bin/nodemon bin/www",
"prd": "pm2 start bin/www",
"prd": "cross-env NODE_ENV=production pm2 start bin/www",
},
}

然后通过 npm run dev 启动项目即可。

二、Context 对象

Koa Context 将 node 的 requestresponse 对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法。每个请求都将创建一个 Context:

app.use(async ctx => {
ctx; // 这是 Context
ctx.request; // 这是 koa Request
ctx.response; // 这是 koa Response
});

常用 API 如下:

  • ctx.req:Node 的 request 对象;
  • ctx.res:Node 的 response 对象;注意绕过 Koa 的 response 处理是不被支持的,应避免使用以下 node 属性:
    • res.statusCode
    • res.writeHead()
    • res.write()
    • res.end()
  • ctx.request:koa 的 Request 对象;
  • ctx.response:koa 的 Response 对象;
  • ctx.app:应用程序实例引用;
  • ctx.cookies.get(name, [options]):通过 options 获取 cookie name
  • ctx.cookies.set(name, value, [options]):通过 options 设置 cookie namevalue可选属性如下:
    • maxAge:number, 表示从 Date.now() 得到的毫秒数;
    • expires:Date 对象, 表示 cookie 的到期日期 (默认在会话结束时过期)
    • path:string, 表示 cookie 的路径 (默认为 /)
    • domain:string, 指示 cookie 的域 (无默认值)
    • secure:boolean, 表示 cookie 是否仅通过 HTTPS 发送 (HTTP 下默认为 false, HTTPS 下默认为 true)
    • httpOnly:boolean, 表示 cookie 是否仅通过 HTTP(S) 发送,, 且不提供给客户端 JavaScript (默认为 true)
    • sameSite:boolean | string, 表示该 cookie 是否为 "相同站点" cookie (默认为 false). 可以设置为 'strict', 'lax', 'none', 或 true (映射为 'strict')
    • signed:boolean, 表示是否要对 cookie 进行签名 (默认为 false)
    • overwrite:boolean, 表示是否覆盖以前设置的同名的 cookie (默认是 false)
  • ctx.throw([status], [msg], [properties]):抛出一个包含 .status 属性错误的帮助方法,其默认值为 500点击查看详情

1、Request 对象

  • ctx.header:请求头对象;
  • ctx.headers:设置请求头对象;
  • ctx.method:请求方法;
  • ctx.method=:设置请求方法;
  • ctx.url:获取请求 URL;
  • ctx.url=:设置请求 URL;
  • ctx.originalUrl:获取请求原始 URL;
  • ctx.origin:获取 URL 的来源,包括 protocolhost
  • ctx.href:获取完整的请求 URL,包括 protocolhosturl
  • ctx.path:获取请求路径名;
  • ctx.path=:设置请求路径名;
  • ctx.query:获取解析的查询字符串, 当没有查询字符串时,返回一个空对象;
  • ctx.query=:将查询字符串设置为给定对象;
  • ctx.querystring:根据 ? 获取原始查询字符串;
  • ctx.querystring=:设置原始查询字符串;
  • ctx.host:存在时获取主机(hostname:port);
  • ctx.hostname:存在时获取主机名;
  • ctx.fresh:检查请求缓存是否新鲜,即内容没有改变;
  • ctx.stale:与 request.fresh 相反;
  • ctx.socket:返回请求套接字;
  • ctx.protocol:返回请求协议,https 或 http;
  • ctx.secure:通过 ctx.protocol == "https" 来检查请求是否通过 TLS 发出;
  • ctx.ip:请求远程地址;
  • ctx.ips:当 X-Forwarded-For 存在且 app.proxy 被启用时,这些 ips 的数组被返回,从上游到下游排序,禁用时返回一个空数组;
  • ctx.subdomains:以数组形式返回子域;
  • ctx.is():检查传入请求是否包含 Content-Type 消息头字段,并且包含任意的 mime type
  • ctx.accepts():检查给定的 type(s) 是否可以接受;
  • ctx.acceptsEncodings():检查 encodings 是否可以接受;
  • ctx.acceptsCharsets():检查 charsets 是否可以接受;
  • ctx.acceptsLanguages():检查 langs 是否可以接受;
  • ctx.get(field):返回具体请求头, field 不区分大小写。

2、Response 对象

  • ctx.body:获取响应体;
  • ctx.body=:设置响应体;
  • ctx.status:获取响应状态;
  • ctx.status=:通过数字代码设置响应状态;
  • ctx.message:获取响应的状态消息;
  • ctx.message=:将响应的状态消息设置为给定值;
  • ctx.length=:将响应的 Content-Length 设置为给定值;
  • ctx.length:以数字返回响应的 Content-Length,或者从ctx.body推导出来,或者undefined
  • ctx.type=:设置响应 Content-Type 通过 mime 字符串或文件扩展名;
  • ctx.type:获取响应 Content-Type, 不含 "charset" 等参数;
  • ctx.headerSent:检查是否已发送响应标头;
  • ctx.redirect(url):执行 302 重定向到 url
  • ctx.attachment([filename], [options]):将 Content-Disposition 设置为 “附件” 以指示客户端提示下载;
  • ctx.set(field, value):设置响应头 fieldvalue
  • ctx.append(field, val):用值 val 附加额外的消息头 field
  • ctx.remove(field):删除消息头 field
  • ctx.lastModified=:将 Last-Modified 消息头设置为适当的 UTC 字符串;
  • ctx.etag=:设置包含 " 包裹的 ETag 响应。

三、Koa 框架下开发接口

点击查看原生 Node.js 项目开发接口

app.js
// ...
const blog = require('./routes/blog')

// ...
app.use(blog.routes(), blog.allowedMethods())

// ...

四、配置与连接 MySQL 数据库

  1. 数据模型建立及分离
  2. 配置和连接 MySQL 数据库方法

配置和连接完,接下来进行接口对接开发:

routes/blog.js
const router = require('koa-router')()
const {
getTotal,
getList,
getDetail
} = require('../controller/blog')
const { SuccessModel, ErrorModel } = require('../model/resModel')

router.prefix('/api/blog')

// 获取博客列表总数
router.get('/count', async function (ctx, next) {
const result = await getTotal()

ctx.body = new SuccessModel(result)
})

// 获取博客列表
router.post('/list', async (ctx, next) => {
const { page_num, page_size } = ctx.request.body
const result = await getList(page_num, page_size)

ctx.body = new SuccessModel(result)
});

// 获取博客详情
router.post('/detail', async (ctx, next) => {
const { id } = ctx.request.body
const result = await getDetail(id)

ctx.body = new SuccessModel(result)
});

module.exports = router

点击查看搭建 Koa 项目完整代码