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' })
})在不同平台的配置方式:
Cloudflare Workers
ts// wrangler.toml [vars] API_KEY = "your-secret-key" [[r2_buckets]] binding = "MY_BUCKET" bucket_name = "my-assets"Node.js (Vercel, etc.)
通过.env文件或环境变量注入:plaintextAPI_KEY=your-secret-key DATABASE_URL=...Hono Dev Server
启动时传入:bashnpx hono dev --env .env.local
最佳实践:
绝不硬编码密钥:使用
c.env注入;类型安全:为
c.env定义类型,避免any:tstype 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.req、c.env、c.var 的用法,你就掌握了 Hono 应用开发的“中枢神经”。