Skip to content

与 Vite 集成:开发时代理 API 请求到 Hono

vite.config.ts 中配置 server.proxy

在现代前端开发中,使用 Vite 作为开发服务器,并将 API 请求代理到后端服务(如 Hono)是一种常见且高效的开发模式。这样可以避免 CORS 问题,并模拟生产环境的请求路径。

本文将详细介绍如何在 vite.config.ts 中通过 server.proxy 配置,将 Vue3/React 应用的 API 请求代理到本地运行的 Hono 服务。

一、典型开发架构

+------------------+          +------------------+
|   Vite Dev Server | <--->    |   Hono Backend   |
| (http://localhost:5173) |     | (http://localhost:3000) |
+------------------+          +------------------+
       |                               |
       +-------- Browser Requests ----+
  • 前端资源由 Vite 提供(/, /assets/*);
  • 所有 /api/* 请求被代理到 Hono 后端;
  • 开发时无需跨域处理。

二、基础配置:vite.config.ts

ts
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 5173,
    open: true,
    proxy: {
      // 代理所有 /api 开头的请求
      '/api': {
        target: 'http://localhost:3000', // Hono 服务地址
        changeOrigin: true,              // 修改 Host 头为目标地址
        secure: false,                   // 不验证 HTTPS 证书
        rewrite: (path) => path.replace(/^\/api/, '/api') // 可选重写
      }
    }
  }
})
配置说明:
选项作用
target指定 Hono 后端服务地址
changeOrigin将 Origin 改为目标地址,避免 Host 不匹配
secure如果目标是 HTTPS 且自签名证书,设为 false
rewrite重写路径(例如去掉 /api 前缀)

三、Hono 后端示例

ts
// backend/index.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/api/hello', (c) => {
  return c.json({ message: 'Hello from Hono!', time: new Date().toISOString() })
})

app.post('/api/data', async (c) => {
  const body = await c.req.json()
  return c.json({ 
    received: body,
    status: 'success' 
  })
})

// 监听 3000 端口
const port = 3000
console.log(`Hono is running on http://localhost:${port}`)
export const serve = app.fetch

启动命令:

bash
# 使用 wrangler(Workers)
wrangler dev

# 或使用 Bun/Node.js
bun run backend/index.ts

四、前端调用(Vue3 示例)

ts
// composables/useApi.ts
export function useApi() {
  const fetchData = async () => {
    try {
      const res = await fetch('/api/hello')
      const data = await res.json()
      console.log(data)
    } catch (err) {
      console.error('Fetch failed:', err)
    }
  }

  const postData = async (payload: any) => {
    const res = await fetch('/api/data', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    })
    return await res.json()
  }

  return { fetchData, postData }
}

注意:前端请求的是 /api/...,Vite 会自动代理到 http://localhost:3000/api/...

五、高级代理配置

1. 多个 API 前缀代理
text
proxy: {
  '/api/auth': {
    target: 'http://localhost:3001',
    changeOrigin: true
  },
  '/api/user': {
    target: 'http://localhost:3002',
    changeOrigin: true
  },
  '/api/product': {
    target: 'http://localhost:3003',
    changeOrigin: true
  }
}
2. WebSocket 代理(用于 SSE 或 WS)
text
'/ws': {
  target: 'ws://localhost:3000',
  ws: true,
  changeOrigin: true
}
3. 路径重写(API 前缀映射)
text
'/backend': {
  target: 'http://localhost:3000',
  changeOrigin: true,
  rewrite: (path) => path.replace(/^\/backend/, '') // 去掉 /backend 前缀
}

这样 /backend/usershttp://localhost:3000/users

4. 添加请求头(如认证)
text
'/api': {
  target: 'http://localhost:3000',
  changeOrigin: true,
  configure: (proxy, options) => {
    proxy.on('proxyReq', (proxyReq, req, res) => {
      // 添加自定义头
      proxyReq.setHeader('x-developer-mode', 'true')
      
      // 透传 Authorization
      const auth = req.headers['authorization']
      if (auth) {
        proxyReq.setHeader('authorization', auth)
      }
    })
  }
}

六、常见问题与解决

问题原因解决方案
503 Service UnavailableHono 服务未启动确保 npm run dev:backend 已运行
404 Not Found路径不匹配检查 Hono 路由是否包含 /api 前缀
CORS Error代理未生效检查 changeOrigin 是否为 true
WebSocket connection failed未启用 ws: trueWebSocket 代理需显式开启
请求卡住网络防火墙检查端口是否被占用或防火墙阻止

七、生产环境注意事项

环境代理策略
开发Vite server.proxy
生产Nginx / Cloudflare / CDN 反向代理
nginx
# Nginx 生产配置示例
location /api/ {
  proxy_pass http://hono-backend:3000/;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
}

不要在生产环境中依赖 Vite 的代理。

八、最佳实践

  1. 统一 API 前缀:使用 /api/bff 作为代理标识;
  2. 环境变量控制
    ts
    // .env.development
    VITE_API_BASE=/api
    
    // .env.production
    VITE_API_BASE=`https://api.your-app.com`
    前端使用 import.meta.env.VITE_API_BASE 动态请求;
  3. 错误日志:在 Hono 中添加日志中间件,便于调试;
  4. 热重载兼容:确保 Hono 和 Vite 分别监听不同文件,避免冲突。

九、总结

通过在 vite.config.ts 中配置 server.proxy,你可以:

  • 无缝集成 Vite 与 Hono;
  • 避免 CORS 问题;
  • 模拟生产路径,减少部署差异;
  • 支持 REST、SSE、WebSocket 等多种协议;

这是现代全栈开发的标准实践之一。掌握这一技能,你就能高效地构建基于 Hono + Vite 的前后端分离应用。