【Koa系列】10min快速入门Koa

简介

koa是基于node开发的一个服务端框架,功能同express,但更小巧简单。

官方仓库地址:https://github.com/koajs/koa

创建项目

创建文件夹nodeKoa,执行以下脚本

javascript 复制代码
npm init -y
npm i koa
npm i nodemon

基础示例

创建一个服务器

命令行输入

javascript 复制代码
nodemon app.js

打开浏览器,输入http:localhost:3000即可看到效果

路由

koa没有提供路由模块,我们可以借助其内置的ctx.path获取其请求路径,自己做出判断

javascript 复制代码
//创建一个请求
app.use( ctx => {
    const path = ctx.path
    if(path == "/"){
        ctx.body = "这是首页"
    }else if( path == "/foo"){
        ctx.body = "这是详情页"
    }else{
        ctx.body = "404"
    }
})

但是,这种方式还是比较麻烦的,我们使用它的官方route插件

官方地址:https://github.com/koajs/router

javascript 复制代码
npm install @koa/router

基础示例

javascript 复制代码
/**
 * 使用koa启动一个HTTP服务
 */
const Koa = require("koa")

const Router = require("@koa/router")
//创建实例
const app = new Koa()

const router  = new Router()

router.get("/",ctx => {
    ctx.body = '这是首页'
})

//路由挂载
app
  .use(router.routes())
  .use(router.allowedMethods());

app.listen(3000, () => {
    console.log("服务运行在:http:localhost:3000");
})

路由模块的写法和expresss几乎是一致的

静态资源托管

如果网站提供静态资源(图片、字体什么的),如果为他们单独写一个路由很麻烦也没有必要。koa-stati模块封装了这部分请求

官方文档:https://github.com/koajs/static

安装

javascript 复制代码
npm install koa-static

我们在根目录创建一个public文件夹,里面放一张图片,然后直接访问里面的内容

可以发现,资源文件无法直接访问,我们创建一个静态资源目录

javascript 复制代码
/**
 * 使用koa启动一个HTTP服务
 */
const Koa = require("koa")
const Router = require("@koa/router")
//引入静态资源插件
const static = require("koa-static")

//创建实例
const app = new Koa()
//建立静态托管目录
app.use(static("./public"))

const router  = new Router()

router.get("/",ctx => {
    ctx.body = '这是首页'
})

//路由挂载
app
  .use(router.routes())
  .use(router.allowedMethods());

app.listen(3000, () => {
    console.log("服务运行在:http:localhost:3000");
})

核心代码

javascript 复制代码
//引入静态资源插件
const static = require("koa-static")
//建立静态托管目录
app.use(static("./public"))

这时,可以发现资源已经可以被正常访问了

我们目前的路径是相对路径,这是不安全的,我们应该使用绝对路径.

javascript 复制代码
const path = require('path')
//建立静态托管目录
app.use(static(path.join(__dirname,"./public")))

虚拟路径

资源的目录或中间件可以设置成虚拟路径,需要使用官方的mount中间件

传送门: https://github.com/koajs/mount

安装

javascript 复制代码
npm install koa-mount

使用

javascript 复制代码
const mount = require('koa-mount')
//建立静态托管目录
app.use( mount('/public',static(path.join(__dirname,"./public"))))

路由重定向

请求bar路径,重定向到boo

javascript 复制代码
router.get('/bar',ctx => {
  //重定向针对的同步请求
  ctx.redirect('/boo')
)

中间件

koa最大的特色,就是中间件.为了理解中间件.我们先看一下logger(日志功能)的实现

  • 先进后出
  • 最外层首先执行
  • 调用next,把执行权交给下一个中间件最内层的中间件最后执行

logger功能

javascript 复制代码
/**
 * 使用koa启动一个HTTP服务
 */
const Koa = require("koa")

//创建实例
const app = new Koa()

const one = (ctx,next) => {
    console.log(">>> one");
    next()
    console.log("<<< one");
}

const two = (ctx,next) => {
    console.log(">>> two");
    next()
    console.log("<<< two");
}

const three = (ctx,next) => {
    console.log(">>> three");
    next()
    console.log("<<< three");
}

app.use(one)
app.use(two)
app.use(three)

app.listen(3000, () => {
    console.log("服务运行在:http:localhost:3000");
})

输出结果

javascript 复制代码
>>> one
>>> two
>>> three
<<< three
<<< two
<<< one

异步中间件

javascript 复制代码
/**
 * 使用koa启动一个HTTP服务
 */
const Koa = require("koa")

//创建实例
const app = new Koa()

const fs = require('fs')

const util = require("util")

app.use( async (ctx ,next) => {
    const asyReadFile = util.promisify(fs.readFile)
    const data = await asyReadFile("./index.html","utf8")
    ctx.body = data
})


app.listen(3000, () => {
    console.log("服务运行在:http//:localhost:3000");
})

除了在回调函数里指定类型,我们也可以在ctx里直接指定返回的类型

javascript 复制代码
app.use( async (ctx ,next) => {
    const asyReadFile = util.promisify(fs.readFile)
    const data = await asyReadFile("./index.html")
    ctx.type = "html"
    ctx.body = data
})

Koa的中间件合并

当有多个中间件时,我们一个个进行挂载是非常低效的,我们可以使用中间件合并功能。

传送门:https://github.com/koajs/compose

安装

复制代码
npm install koa-compose

示例

复制代码
app.use = compose([a1, a2, a3, ...])

中间件异常处理

正常情况,我们捕获一个错误可能会这么写代码

复制代码
const Koa = require("koa")
//创建实例
const app = new Koa()
app.use( ctx => {
  try {
    JSON.parse("dsssssss")
    ctx.body = "hello koa"
  }catch(err){
    ctx.response.status = 500
    ctx.response.body = "服务端内部错误"
  }
})
app.listen(3000, () => {
  console.log("服务运行在:http://localhost:3000");
})

koa也给我们提供了内置函数简化500的错误响应

复制代码
app.use( ctx => {
    try {
        JSON.parse("dsssssss")
        ctx.body = "hello koa"
    }catch(err){
        ctx.throw(500)
    }
})

对于多个异常,我们可以借助koa的洋葱模型进行捕获,用最外层的中间件进行异常捕获,内层的中间件异常最终全部会被koa最外层的中间件所捕获。

复制代码
const Koa = require("koa");
//创建实例
const app = new Koa();
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    console.log(111);
    ctx.response.status = 500;
    ctx.body = "服务器内部错误";
  }
});
app.use((ctx) => {
  console.log(222);
  JSON.parse("dsssssss");
  ctx.body = "hello koa";
});

app.listen(3000, () => {
  console.log("服务运行在:http://localhost:3000");
});

最外层的中间件函数必须写成async的形式,不然异常不会被捕获进去

相关推荐
我想说一句1 分钟前
掘金移动端React开发实践:从布局到样式优化的完整指南
前端·react.js·前端框架
jqq6662 分钟前
Vue3脚手架实现(九、渲染typescript配置)
前端
码间舞12 分钟前
Zustand 与 useSyncExternalStore:现代 React 状态管理的极简之道
前端·react.js
Dream耀13 分钟前
提升React移动端开发效率:Vant组件库
前端·javascript·前端框架
冰菓Neko14 分钟前
HTML 常用标签速查表
前端·html
gis收藏家38 分钟前
从稀疏数据(CSV)创建非常大的 GeoTIFF(和 WMS)
前端
程序视点1 小时前
望言OCR 2025终极评测:免费版VS专业版全方位对比(含免费下载)
前端·后端·github
NUC_Dodamce1 小时前
Cocos3x 解决同时勾选 适配屏幕宽度和 适配屏幕高度导致Widget组件失效的问题
开发语言·javascript·ecmascript
五点六六六2 小时前
前端常见的性能指标采集
前端·性能优化·架构
吳所畏惧2 小时前
NVM踩坑实录:配置了npm的阿里云cdn之后,下载nodejs老版本(如:12.18.4)时,报404异常,下载失败的问题解决
前端·windows·阿里云·npm·node.js·batch命令