全书目录

第三十四篇:Hono 完全指南 —— 边缘轻骑哨站宇宙

第六站:中间件是沿路哨兵,顺序就是军令

2 分钟 480 字 第 642 / 962 个阅读单元

Hono 的中间件不是装饰品,而是哨站纪律体系。

你可以把它想成:

  • 第一道哨:打日志
  • 第二道哨:验身份
  • 第三道哨:加安全头
  • 第四道哨:限流或限制 body
  • 最后才到哨长真正处理业务

#执行顺序

官方文档的规则非常明确:

  • 注册顺序决定执行顺序
  • await next() 之前是“进站前动作”
  • await next() 之后是“出站收尾动作”

看一个例子:

ts
import { Hono } from 'hono'

const app = new Hono()

app.use(async (_, next) => {
  console.log('哨兵 1 开始')
  await next()
  console.log('哨兵 1 收尾')
})

app.use(async (_, next) => {
  console.log('哨兵 2 开始')
  await next()
  console.log('哨兵 2 收尾')
})

app.get('/', (c) => {
  console.log('哨长处理')
  return c.text('ok')
})

脑内执行顺序是:

text
哨兵1开始
  哨兵2开始
    哨长处理
  哨兵2收尾
哨兵1收尾

#最实用的自定义中间件写法

ts
import { Hono } from 'hono'
import { createMiddleware } from 'hono/factory'

type Variables = {
  riderId: string
}

const auth = createMiddleware<{ Variables: Variables }>(async (c, next) => {
  const authHeader = c.req.header('Authorization')

  if (!authHeader) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  c.set('riderId', 'rider-17')
  await next()
})

const app = new Hono<{ Variables: Variables }>()

app.get('/dispatch', auth, (c) => {
  return c.json({
    ok: true,
    riderId: c.var.riderId,
  })
})

这里你要注意三件事:

  1. createMiddleware() 很适合做可复用中间件
  2. c.set() 是把数据挂到这次请求上下文上
  3. 后续 handler 里可以用 c.var.xxx 类型安全地取出来

#内置装备很多

Hono 官方内置中间件不少,常见就够你覆盖大部分轻服务场景:

  • logger
  • cors
  • secureHeaders
  • bodyLimit
  • requestId
  • timing
  • timeout
  • jwt
  • basicAuth
  • bearerAuth

例如:

ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { secureHeaders } from 'hono/secure-headers'

const app = new Hono()

app.use('*', logger())
app.use('*', secureHeaders())

app.get('/', (c) => c.text('安全巡逻中'))

secureHeaders 的定位很像 Helmet 的轻骑版:快速把常见安全响应头挂上。