Appearance
代理助手
🌐 Proxy Helper
当使用 Hono 应用作为(反向)代理时,Proxy Helper 提供了有用的功能。
🌐 Proxy Helper provides useful functions when using Hono application as a (reverse) proxy.
导入
🌐 Import
ts
import { Hono } from 'hono'
import { proxy } from 'hono/proxy'proxy()
proxy() 是用于代理的 fetch() API 封装。参数和返回值与 fetch() 相同(除了特定于代理的选项之外)。
Accept-Encoding 头被替换为当前运行时可以处理的编码。多余的响应头被移除,并返回一个 Response 对象,该对象可以由处理程序发送。
🌐 The Accept-Encoding header is replaced with an encoding that the current runtime can handle. Unnecessary response headers are removed, and a Response object is returned that can be sent from the handler.
示例
🌐 Examples
简单用法:
🌐 Simple usage:
ts
app.get('/proxy/:path', (c) => {
return proxy(`http://${originServer}/${c.req.param('path')}`)
})复杂用法:
🌐 Complicated usage:
ts
app.get('/proxy/:path', async (c) => {
const res = await proxy(
`http://${originServer}/${c.req.param('path')}`,
{
headers: {
...c.req.header(), // optional, specify only when forwarding all the request data (including credentials) is necessary.
'X-Forwarded-For': '127.0.0.1',
'X-Forwarded-Host': c.req.header('host'),
Authorization: undefined, // do not propagate request headers contained in c.req.header('Authorization')
},
}
)
res.headers.delete('Set-Cookie')
return res
})或者你可以将 c.req 作为参数传递。
🌐 Or you can pass the c.req as a parameter.
ts
app.all('/proxy/:path', (c) => {
return proxy(`http://${originServer}/${c.req.param('path')}`, {
...c.req, // optional, specify only when forwarding all the request data (including credentials) is necessary.
headers: {
...c.req.header(),
'X-Forwarded-For': '127.0.0.1',
'X-Forwarded-Host': c.req.header('host'),
Authorization: undefined, // do not propagate request headers contained in c.req.header('Authorization')
},
})
})你可以使用 customFetch 选项覆盖默认的全局 fetch 函数:
🌐 You can override the default global fetch function with the customFetch option:
ts
app.get('/proxy', (c) => {
return proxy('https://example.com/', {
customFetch,
})
})连接头处理
🌐 Connection Header Processing
默认情况下,proxy() 会忽略 Connection 头,以防止逐跳头注入攻击。你可以使用 strictConnectionProcessing 选项启用严格的 RFC 9110 兼容性:
🌐 By default, proxy() ignores the Connection header to prevent Hop-by-Hop Header Injection attacks. You can enable strict RFC 9110 compliance with the strictConnectionProcessing option:
ts
// Default behavior (recommended for untrusted clients)
app.get('/proxy/:path', (c) => {
return proxy(`http://${originServer}/${c.req.param('path')}`, c.req)
})
// Strict RFC 9110 compliance (use only in trusted environments)
app.get('/internal-proxy/:path', (c) => {
return proxy(`http://${internalServer}/${c.req.param('path')}`, {
...c.req,
strictConnectionProcessing: true,
})
})ProxyFetch
proxy() 的类型定义为 ProxyFetch,具体如下
🌐 The type of proxy() is defined as ProxyFetch and is as follows
ts
interface ProxyRequestInit extends Omit<RequestInit, 'headers'> {
raw?: Request
customFetch?: (request: Request) => Promise<Response>
strictConnectionProcessing?: boolean
headers?:
| HeadersInit
| [string, string][]
| Record<RequestHeader, string | undefined>
| Record<string, string | undefined>
}
interface ProxyFetch {
(
input: string | URL | Request,
init?: ProxyRequestInit
): Promise<Response>
}