Skip to content

Proxy 助手

Proxy 助手提供了一些实用函数,帮助你将 Hono 应用用作(反向)代理。

导入

ts
import { Hono } from 'hono'
import { proxy } from 'hono/proxy'

proxy()

proxy() 是一个封装 fetch() API 的代理函数。除了代理相关的额外选项外,其参数与返回值与 fetch() 相同。

该函数会用当前运行时支持的编码替换 Accept-Encoding 请求头,并清理不必要的响应头,最终返回一个可直接用于响应处理器的 Response 对象。

示例

基础用法:

ts
app.get('/proxy/:path', (c) => {
  return proxy(`http://${originServer}/${c.req.param('path')}`)
})

更复杂的示例:

ts
app.get('/proxy/:path', async (c) => {
  const res = await proxy(
    `http://${originServer}/${c.req.param('path')}`,
    {
      headers: {
        ...c.req.header(), // 可选,只有在需要转发完整请求(包括凭证)时才指定
        'X-Forwarded-For': '127.0.0.1',
        'X-Forwarded-Host': c.req.header('host'),
        Authorization: undefined, // 不转发 c.req.header('Authorization') 中的值
      },
    }
  )
  res.headers.delete('Set-Cookie')
  return res
})

你也可以将 c.req 直接作为参数传入。

ts
app.all('/proxy/:path', (c) => {
  return proxy(`http://${originServer}/${c.req.param('path')}`, {
    ...c.req, // 可选,只有在需要转发完整请求(包括凭证)时才指定
    headers: {
      ...c.req.header(),
      'X-Forwarded-For': '127.0.0.1',
      'X-Forwarded-Host': c.req.header('host'),
      Authorization: undefined, // 不转发 c.req.header('Authorization') 中的值
    },
  })
})

通过 customFetch 选项可以覆盖默认的全局 fetch 函数:

ts
app.get('/proxy', (c) => {
  return proxy('https://example.com/', {
    customFetch,
  })
})

ProxyFetch

proxy() 的类型定义为 ProxyFetch,如下所示:

ts
interface ProxyRequestInit extends Omit<RequestInit, 'headers'> {
  raw?: Request
  customFetch?: (request: Request) => Promise<Response>
  headers?:
    | HeadersInit
    | [string, string][]
    | Record<RequestHeader, string | undefined>
    | Record<string, string | undefined>
}

interface ProxyFetch {
  (
    input: string | URL | Request,
    init?: ProxyRequestInit
  ): Promise<Response>
}

Released under the MIT License.