HonoRequest
HonoRequest 是从 c.req 获取的对象,用于包装 Request 实例。
param()
获取路径参数的值。
// 捕获的参数
app.get('/entry/:id', async (c) => {
const id = c.req.param('id')
// ...
})
// 一次性获取全部参数
app.get('/entry/:id/comment/:commentId', async (c) => {
const { id, commentId } = c.req.param()
})query()
获取查询字符串参数。
// 查询参数
app.get('/search', async (c) => {
const query = c.req.query('q')
})
// 一次性获取全部参数
app.get('/search', async (c) => {
const { q, limit, offset } = c.req.query()
})queries()
获取同名查询参数的多个值,例如 /search?tags=A&tags=B
app.get('/search', async (c) => {
// tags 的类型是 string[]
const tags = c.req.queries('tags')
// ...
})header()
获取请求头的值。
app.get('/', (c) => {
const userAgent = c.req.header('User-Agent')
return c.text(`你的 User-Agent 是 ${userAgent}`)
})WARNING
当 c.req.header() 不带参数调用时,返回对象的所有键都会被转换为小写。
若要读取带有大写名称的请求头,请使用 c.req.header("X-Foo")。
// ❌ 不会生效
const headerRecord = c.req.header()
const foo = headerRecord['X-Foo']
// ✅ 可行
const foo = c.req.header('X-Foo')parseBody()
解析 multipart/form-data 或 application/x-www-form-urlencoded 类型的请求体。
app.post('/entry', async (c) => {
const body = await c.req.parseBody()
// ...
})parseBody() 支持以下场景:
单文件
const body = await c.req.parseBody()
const data = body['foo']
body['foo'] 的类型为 (string | File)。
如果上传了多个文件,会保留最后一个。
多文件
const body = await c.req.parseBody()
body['foo[]']body['foo[]'] 始终是 (string | File)[]。
必须带上 [] 后缀。
同名的多个文件或字段
当存在允许多选的文件输入 <input type="file" multiple />,或有多个同名复选框 <input type="checkbox" name="favorites" value="Hono"/> 时:
const body = await c.req.parseBody({ all: true })
body['foo']all 选项默认关闭。
- 如果
body['foo']对应多个文件,将解析为(string | File)[]。 - 如果
body['foo']是单个文件,将解析为(string | File)。
点符号
当 dot 选项设为 true 时,返回值会根据点语法构建层级。
假设收到如下数据:
const data = new FormData()
data.append('obj.key1', 'value1')
data.append('obj.key2', 'value2')启用 dot: true 后即可得到结构化结果:
const body = await c.req.parseBody({ dot: true })
// body 为 `{ obj: { key1: 'value1', key2: 'value2' } }`json()
解析 application/json 类型的请求体。
app.post('/entry', async (c) => {
const body = await c.req.json()
// ...
})text()
解析 text/plain 类型的请求体。
app.post('/entry', async (c) => {
const body = await c.req.text()
// ...
})arrayBuffer()
将请求体解析为 ArrayBuffer。
app.post('/entry', async (c) => {
const body = await c.req.arrayBuffer()
// ...
})blob()
将请求体解析为 Blob。
app.post('/entry', async (c) => {
const body = await c.req.blob()
// ...
})formData()
将请求体解析为 FormData。
app.post('/entry', async (c) => {
const body = await c.req.formData()
// ...
})valid()
获取校验后的数据。
app.post('/posts', async (c) => {
const { title, body } = c.req.valid('form')
// ...
})可用的目标如下:
formjsonqueryheadercookieparam
参见验证章节了解使用示例。
routePath
WARNING
v4.8.0 起已弃用:该属性已废弃,请改用 Route Helper 提供的 routePath()。
可以在处理函数中这样获取已注册的路径:
app.get('/posts/:id', (c) => {
return c.json({ path: c.req.routePath })
})访问 /posts/123 时会返回 /posts/:id:
{ "path": "/posts/:id" }matchedRoutes
WARNING
v4.8.0 起已弃用:该属性已废弃,请改用 Route Helper 提供的 matchedRoutes()。
它会在处理函数中返回匹配到的路由,便于调试。
app.use(async function logger(c, next) {
await next()
c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
const name =
handler.name ||
(handler.length < 2 ? '[处理函数]' : '[中间件]')
console.log(
method,
' ',
path,
' '.repeat(Math.max(10 - path.length, 0)),
name,
i === c.req.routeIndex ? '<- 从这里响应' : ''
)
})
})path
请求的路径名。
app.get('/about/me', async (c) => {
const pathname = c.req.path // `/about/me`
// ...
})url
请求的完整 URL 字符串。
app.get('/about/me', async (c) => {
const url = c.req.url // `http://localhost:8787/about/me`
// ...
})method
请求使用的方法名称。
app.get('/about/me', async (c) => {
const method = c.req.method // `GET`
// ...
})raw
原始的 Request 对象。
// 适用于 Cloudflare Workers
app.post('/', async (c) => {
const metadata = c.req.raw.cf?.hostMetadata?
// ...
})