You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于Hono for Vercel的后端API中使用Vercel Middleware

在Hono for Vercel里用Vercel Edge Middleware的正确姿势

先把项目结构捋对

Vercel的Edge Middleware必须放在项目根目录,文件名得是middleware.js或者middleware.ts,不能瞎改后缀。同时你的Hono API文件要放在api/目录下(这是Vercel默认识别Serverless/Edge函数的目录),示例结构如下:

你的项目/
├── middleware.js       # 核心中间件文件,必须放根目录
├── api/
│   └── index.js        # Hono的API入口文件
└── vercel.json         # 可选,用来自定义路由规则

编写Middleware,按路由分配处理逻辑

用Vercel Middleware的matcher指定哪些路由要触发中间件,然后根据不同路由写对应的处理函数,效果和Next.js的文件夹路由逻辑一致:

// middleware.js
import { NextResponse } from 'next/server';

// 指定要匹配的路由,和Hono的路由对应上
export const config = {
  matcher: [
    '/api/users/:path*',  // 匹配/api/users下所有子路由
    '/api/posts/:path*',  // 匹配/api/posts下所有子路由
    '/api/auth/:path*'    // 匹配/api/auth下所有子路由
  ],
};

export function middleware(request) {
  const { pathname } = request.nextUrl;

  // 按路由分支处理,想加多少路由就加多少
  if (pathname.startsWith('/api/users')) {
    return handleUserRoutes(request);
  } else if (pathname.startsWith('/api/posts')) {
    return handlePostRoutes(request);
  } else if (pathname.startsWith('/api/auth')) {
    return handleAuthRoutes(request);
  }

  // 没匹配到的路由直接放行
  return NextResponse.next();
}

// 每个路由对应的中间件逻辑,单独拆出来更清晰
function handleUserRoutes(request) {
  // 比如做用户权限校验、访问日志
  console.log('用户路由被访问:', request.url);
  // 没问题就放行,也可以修改响应
  return NextResponse.next();
}

function handlePostRoutes(request) {
  // 比如校验POST请求的参数格式
  if (request.method === 'POST') {
    // 这里写你的校验逻辑
  }
  return NextResponse.next();
}

function handleAuthRoutes(request) {
  // 比如校验请求头里的Token
  const token = request.headers.get('Authorization');
  if (!token) {
    return new NextResponse('未授权', { status: 401 });
  }
  return NextResponse.next();
}

确保Hono和Middleware兼容

Hono的API正常写就行,Middleware会在Hono处理请求之前触发,完全不冲突。示例Hono代码:

// api/index.js
import { Hono } from 'hono';
import { handle } from 'hono/vercel';

const app = new Hono();

// 对应Middleware里的路由
app.get('/api/users', (c) => c.json({ message: '用户列表' }));
app.get('/api/posts', (c) => c.json({ message: '文章列表' }));
app.post('/api/auth/login', (c) => c.json({ token: '模拟令牌' }));

export default handle(app);

解决你之前Middleware没命中的问题

你之前放根目录没生效,大概率是这几个原因:

  • 文件名不对:必须是middleware.js/middleware.ts,不能是middleware.jsx或者别的名字
  • matcher规则写错了:比如你的Hono路由是/api/users,但matcher里没写/api/users/:path*,导致没匹配上
  • 本地测试方式错了:不能直接用node启动,得用vercel dev来跑,因为Middleware是Vercel Edge Runtime的特性,本地node环境不支持
  • vercel.json有冲突:如果自定义了路由规则,可能覆盖了Middleware的匹配逻辑,检查一下这个文件

进阶:Hono中间件+Vercel Middleware配合用

如果需要更细的路由控制,也可以在Hono内部写路由级的中间件,Vercel Middleware用来做全局的事情(比如IP限制、CORS配置),两者搭配着用更灵活:

// api/index.js
const userRouter = new Hono();
// Hono自己的路由中间件,只作用于/api/users下的路由
userRouter.use('*', async (c, next) => {
  console.log('Hono用户路由中间件触发');
  await next();
});
userRouter.get('/', (c) => c.json({ users: [] }));

app.route('/api/users', userRouter);

内容的提问来源于stack exchange,提问作者pcrocks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 05:26:12