cms做网站可以做些什么网站,百度竞价投放,seo外贸网站制作,如何把自己做的网站Koa 介绍
Koa 是一个新的 web 框架#xff0c;由 Express 幕后的原班人马打造#xff0c;致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 官网#xff1a;https://koajs.com/GitHub 仓库#xff1a;https://github.com/koajs/koa一个翻译…Koa 介绍
Koa 是一个新的 web 框架由 Express 幕后的原班人马打造致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 官网https://koajs.com/GitHub 仓库https://github.com/koajs/koa一个翻译的中文网https://koa.bootcss.com/ Koa 的原理和内部结构很像 Express但是语法和内部结构进行了升级Koa 内部使用 ES6 编写号称是下一代 Node.js Web 框架它的主要特点是通过利用 async 函数帮你丢弃回调函数 Koa 1 是基于 ES2015 中的 Generator 生成器函数结合 CO 模块Koa 2 完全抛弃了 Generator 和 co升级为了 ES2017 中的 async/await 函数 正是由于 Koa 内部基于最新的异步处理方式所以使用 Koa 处理异常更加简单Koa 中提供了 context 上下文对象 Koa 包装和扩展了 Nodejs 中的 req 和 resExpress 只是扩展了 req 和 res Koa 并没有捆绑任何中间件 而是提供了一套优雅的方法帮助您快速而愉快地编写服务端应用程序。 Koa 本身并不支持路由、模板、发送文件、JSONP 等功能需要单独安装对应的中间件 有很多开发工具/框架都是基于 Koa 的 Egg.js - 企业级 Web 开发框架构建工具 Vite - Vue 3 构建工具 Koa vs Express 官方对比其他评价 koa 2 好用设计上的确有优势。优势不在能实现更强的功能而是可以更简单地完成功能。koa 2 社区远不如 expresskoa 1 在思想上与 koa 2 是一致的但是 koa 2 的实现更漂亮 Awesome Koa - 第三方仓库收录了一些和 Koa 相关的资源教程、中间件等
Koa 基本使用
使用 Koa 启动一个 HTTP 服务
npm init -y
# 安装 koa
npm i koa// app.js
const Koa require(koa)const app new Koa()// Koa 没有路由系统只有中间件功能
// ctx:context 上下文对象包含请求和响应相关方法
app.use(ctx {// 发送响应ctx.body Hello Koa
})app.listen(3000, () {console.log(server is running on http://localhost:3000)
})
nodemon ./app.jsKoa 中的路由
Koa 本身不自带路由功能如果想要对不同的请求路径进行分发处理需要自己手动编码处理。
app.use(ctx {const path ctx.pathconsole.log(path);if (path /) {ctx.body home page} else if (path /foo) {ctx.body foo page} else {ctx.body 404 Not Found.}
})实际上 Koa 将一些功能单独封装成 npm 包其中包括路由功能。
在 Koa.js (github.com) 中搜索 route 仓库可以找到几个官方提供的路由工具包推荐使用 koajs/router它使用 Express 风格的方法app.get、app.post 等详情参考API 文档。
# 安装
npm i koa/router// app.js
const Koa require(koa)
const Router require(koa/router)const app new Koa()
const router new Router()router.get(/, ctx {ctx.body home page
})router.post(/, ctx {ctx.body post /
})router.get(/foo, ctx {ctx.body foo page
})router.get(/bar, ctx {// 重定向ctx.redirect(/foo)
})router.get(/users/:id, ctx {ctx.body ctx.params
})app// 挂载路由配置.use(router.routes())// 配置允许的请求方法OPTIONS 请求的 Allow 请求头.use(router.allowedMethods())app.listen(3000, () {console.log(server is running on http://localhost:3000)
})
Koa 中的静态资源托管
koajs/static 模块封装了静态资源托管的功能。
npm i koa-static// app.js
const Koa require(koa)
const static require(koa-static)
const path require(path)const app new Koa()// http://localhost:3000/css/style.css 访问 /public/css/style.css 文件
app.use(static(path.join(__dirname, ./public)))app.listen(3000, () {console.log(server is running on http://localhost:3000)
})
Koa 的中间件不能通过第一个参数设置请求路径通过下面的方式给静态资源目录添加虚拟路径会报错
app.use(/public, static(path.join(__dirname, ./public)))可以使用 Koa 的另一个模块 koajs/mount 将 Koa 应用或中间件装载到指定路径
npm i koa-mount// mount(路径, 中间件)
app.use(mount(/public, static(path.join(__dirname, ./public))))Koa 中间件
中间件执行栈
Koa 最大的特色和 Express 一样也是完全基于中间件middleware构建的 web 框架。
Koa 中间件和 Express 中间件有很大的区别Koa 中间件完全基于洋葱模型如图 多个中间件会形成一个栈结构middle stack以“先进后出”first-in-last-out的顺序执行。最外层的中间件首先执行。调用 next 函数的时候会把执行权交给下一个中间件…最内层的中间件最后执行执行结束后把执行权交回上一层的中间件…最外层的中间件收回执行权后执行 next 函数后面的代码
下面通过代码查看中间件的栈结构
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)打印结果 onetwothreethreetwoone如果中间件内部没有调用 next 函数那么执行权就不会传递下去。例如将 two 函数中的 next() 注释打印结果 onetwotwoone异步中间件
迄今为止所有例子的中间件都是同步的不包含异步操作。如果有异步操作比如读取数据库、读取文件中间件就必须写成 async 函数
const Koa require(koa)
const path require(path)
const fsPromises require(fs).promisesconst app new Koa()app.use(async (ctx, next) {const data await fsPromises.readFile(path.join(__dirname, ./views/index.html))// 设置 content-type 为 text/html// 或者在读取文件的时候设置编码为 utf8ctx.type htmlctx.body datanext()
})app.listen(3000, () {console.log(server is running on http://localhost:3000)
})合并多个中间件
Koa 默认只能一个一个挂载中间件
app.use(one)
app.use(two)
app.use(three)可以使用中间件组合工具 koajs/compose将多个中间件合并成同一个中间件去挂载。
npm i koa-composeapp.use(compose([one, two, three]))全局异常处理
下面是捕获并手动响应错误的中间件
app.use(ctx {try {JSON.parse(string)ctx.body Hello Koa} catch (error) {ctx.response.status 500ctx.response.body 服务端内部错误}
})也可以使用 Koa 提供的快捷方法 ctx.throw 来响应错误
app.use(ctx {try {JSON.parse(string)ctx.body Hello Koa} catch (error) {// ctx.response.status 500// ctx.response.body 服务端内部错误// ctx.throw(500) // body Internal Server Errorctx.throw(404) // body Not Found}
})上例是对单个中间件的错误捕获处理如果要统一的处理程序中的异常就要利用洋葱中间件的模型将捕获错误的代码写在最外层
const Koa require(koa)
const app new Koa()// 最外层添加异常捕获的中间件
app.use((ctx, next) {try {next()} catch (error) {ctx.response.status 500ctx.response.body error.message}
})app.use(ctx {JSON.parse(string)ctx.body Hello Koa
})...可以看到 Koa 处理错误的方式相比 Express 方便一些不需要在每个中间件中 try-catch 捕获错误并将错误传递给 next。
注意上例使用的都是同步中间件如果是异步中间件就要在 try-catch 中使用 await
// 最外层添加异常捕获的中间件
app.use(async (ctx, next) {try {// 使用 await 等待下一个中间件处理完成await next()} catch (error) {ctx.response.status 500ctx.response.body error.message}
})// 同步中间件A
app.use((ctx, next) {next()
})// 异步中间件B
app.use(async ctx {// 读取不存在的文件await fsPromises.readFile(file.txt)
})但是这样不会捕获中间件 B 的错误因为上层的中间件 A 是同步的并未等待下层中间件的结果最外层的错误处理中间件 await 的是中间件 A 的执行结果。
解决办法有
// 方案一同步中间件返回下层中间件的执行结果
// 同步中间件A
app.use((ctx, next) {return next()
})// 方案二将同步中间件改为异步中间件await next()
// 同步中间件A
app.use(async (ctx, next) {await next()
})这属于 JS 的 Promise 语法问题与 Koa 和中间件无关。
建议所有的中间件都使用 asycn 异步函数使用 await 等待 next()。
另一种异步处理方式
除了使用外层中间件的方式捕获错误Koa 还可以通过监听 error 事件捕获错误
// 可以在任意位置监听事件
app.on(error, err {console.log(err)
})**注意**使用外层中间件 try-catch 捕获并处理了错误并不会触发 error 事件。
如果既要在中间件中处理异常又要触发 error 事件可以在中间件中手动触发 error 事件
// 最外层添加异常捕获的中间件
app.use(async (ctx, next) {try {await next()} catch (error) {ctx.response.status 500ctx.response.body error.message// 触发 error 事件ctx.app.emit(error, error, ctx)}
})实际项目中使用二者之一即可建议使用中间件。