Skip to content

Context 对象:c 的核心属性与方法

c.req(Request 封装)、c.env(环境变量)、c.var(中间件数据传递)

在 Hono 中,Context(简称 c 是请求处理过程中的核心对象。它封装了 HTTP 请求、响应、环境变量和自定义数据,是中间件、路由处理器与外部世界交互的“桥梁”。理解 c 的结构和用法,是掌握 Hono 开发的关键。


一、c.req:请求的封装与便捷访问

c.req 是对原生 Request 对象的增强封装,提供了更简洁、更安全的 API 来读取请求数据。

核心功能:
方法/属性说明
c.req.url请求完整 URL
c.req.method请求方法(GET、POST 等)
c.req.path请求路径(不含查询参数)
c.req.query()解析查询字符串,返回对象
c.req.query(name)获取单个查询参数
c.req.param()获取路径参数(来自路由)
c.req.param(name)获取指定路径参数
c.req.header(name)获取请求头
c.req.headers获取所有请求头(Headers 对象)
c.req.body()异步读取请求体(支持自动解析 JSON、表单等)
c.req.json<T>()便捷读取 JSON 请求体
c.req.text()读取文本请求体
c.req.formData()读取 multipart/form-data
示例:
ts
app.get('/users/:id', async (c) => {
  // 路径参数
  const id = c.req.param('id') // /users/123 → '123'

  // 查询参数
  const page = c.req.query('page') // /users/123?page=2 → '2'
  const query = c.req.query() // → { page: '2', sort: 'name' }

  // 请求头
  const userAgent = c.req.header('User-Agent')
  const contentType = c.req.header('content-type') // 不区分大小写

  // 请求体(POST/PUT)
  const body = await c.req.json() // 自动解析 JSON
  // const text = await c.req.text()
  // const form = await c.req.formData()

  return c.json({ id, page, userAgent, body })
})
优势:
  • 类型安全c.req.param('id') 直接返回 string
  • 简化解析:无需手动调用 request.json()
  • 统一接口:无论部署在哪个平台(Node.js、Workers、Deno),API 一致。

二、c.env:环境变量与平台绑定

c.env 是一个只读对象,用于访问环境变量平台绑定资源(如 KV、D1、R2 等)。

使用场景:
ts
app.get('/secret', (c) => {
  const apiKey = c.env.API_KEY
  const db = c.env.DB // Cloudflare D1 数据库
  const bucket = c.env.MY_BUCKET // R2 存储桶

  if (!apiKey) {
    return c.text('API Key missing', 500)
  }

  return c.json({ key: 'masked' })
})
在不同平台的配置方式:
  1. Cloudflare Workers

    ts
    // wrangler.toml
    [vars]
    API_KEY = "your-secret-key"
    
    [[r2_buckets]]
    binding = "MY_BUCKET"
    bucket_name = "my-assets"
  2. Node.js (Vercel, etc.)
    通过 .env 文件或环境变量注入:

    plaintext
    API_KEY=your-secret-key
    DATABASE_URL=...
  3. Hono Dev Server
    启动时传入:

    bash
    npx hono dev --env .env.local
最佳实践:
  • 绝不硬编码密钥:使用 c.env 注入;

  • 类型安全:为 c.env 定义类型,避免 any

    ts
    type Env = {
      API_KEY: string
      DB: D1Database
      MY_BUCKET: R2Bucket
    }
    
    const app = new Hono<{ Bindings: Env }>()

三、c.var:中间件间的安全数据传递

c.var 是一个类型安全的存储空间,用于在中间件之间传递数据。它是 c.set()c.get() 的底层实现。

核心方法:
  • c.set(key: string, value: any):设置值
  • c.get(key: string):获取值
  • c.var:直接访问所有已设置的值(类型安全)
示例:JWT 中间件传递用户信息
ts
// JWT 认证中间件
const auth = async (c: Context, next: Next) => {
  const token = c.req.header('Authorization')?.split(' ')[1]
  if (!token) return c.json({ error: 'Unauthorized' }, 401)

  try {
    const payload = await verify(token, c.env.JWT_SECRET)
    c.set('user', payload) // 将用户信息注入上下文
    await next()
  } catch {
    return c.json({ error: 'Invalid token' }, 401)
  }
}

// 路由处理器
app.get('/profile', auth, (c) => {
  const user = c.var.user // 类型安全获取
  // 或 const user = c.get('user')
  return c.json({ profile: user })
})
为什么使用 c.var 而不是闭包或全局变量?
  • 请求隔离:每个请求有独立的 c 实例,数据不会串扰;
  • 类型安全:配合 TypeScript,c.var.user 可推导类型;
  • 可组合:中间件可安全地注入数据,供下游使用;
  • 非持久化:数据仅在当前请求生命周期内有效。
类型定义技巧:
ts
type CustomVars = {
  user: { sub: string; name: string }
  userAgent: string
}

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

// 现在 c.var.user 有正确类型

四、总结:c 是 Hono 的“瑞士军刀”

属性用途特性
c.req读取请求数据封装、便捷、类型安全
c.env访问环境与平台资源只读、部署相关、安全
c.var中间件数据传递请求局部、类型安全、可组合

Context 对象的设计体现了 Hono 的哲学:

  • 极简核心:不依赖全局状态;
  • 函数式风格:数据通过参数(c)传递;
  • 平台无关:统一接口,适配多运行时。

掌握 c.reqc.envc.var 的用法,你就掌握了 Hono 应用开发的“中枢神经”。