【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 分钟前
vue2+elementui使用compressorjs压缩上传的图片
前端·javascript·elementui
The_cute_cat3 分钟前
JavaScript的初步学习
开发语言·javascript·学习
海天胜景6 分钟前
vue3 el-table 列增加 自定义排序逻辑
javascript·vue.js·elementui
今晚打老虎z10 分钟前
dotnet-env: .NET 开发者的环境变量加载工具
前端·chrome·.net
用户38022585982415 分钟前
vue3源码解析:diff算法之patchChildren函数分析
前端·vue.js
烛阴20 分钟前
XPath 进阶:掌握高级选择器与路径表达式
前端·javascript
小鱼小鱼干24 分钟前
【JS/Vue3】关于Vue引用透传
前端
JavaDog程序狗26 分钟前
【前端】HTML+JS 实现超燃小球分裂全过程
前端
独立开阀者_FwtCoder31 分钟前
URL地址末尾加不加 "/" 有什么区别
前端·javascript·github
独立开阀者_FwtCoder34 分钟前
Vue3 新特性:原来watch 也能“暂停”和“恢复”了!
前端·javascript·github