中间件必须显式挂载才能生效,仅定义函数不调用app.Use()或路径注册则不会执行;全局用app.Use(),局部需绑定到具体路由,且须注意执行顺序、StopExecution终止和参数/Body读取等边界控制。

中间件必须用 app.Use() 或按路径注册,不能只写函数不挂载
写好一个函数型中间件后,Iris 不会自动执行它——你得显式告诉框架“这个中间件要作用于哪些请求”。常见错误是定义了 func(ctx iris.Context) 却没调用 app.Use() 或 app.Get("/path", middleware, handler),结果中间件完全不触发。
全局拦截用 app.Use(middleware);若只想对 API 路径生效,推荐 app.Any("/api/*", middleware, iris.Handlers{handler}) 或分方法注册(如 app.Post("/api/login", authMiddleware, loginHandler))。
-
app.Use()注册的中间件对所有路由生效(包括/health、/favicon.ico),需在中间件内部用ctx.Path()和ctx.Method()显式跳过免检路径 - 别把中间件塞进某个具体 handler 里(比如只在
POST /order里校验签名),其他接口就绕过了,安全策略失效 - 多个中间件顺序很重要:
app.Use(a, b, c)表示 a → b → c → handler,越靠前的越先执行
中间件里写响应后必须调 ctx.StopExecution(),否则后续逻辑仍会执行
Iris 的 ctx.Next() 是“继续往下走”,不是“中断当前流程”。如果你在中间件里已经写了 ctx.JSON(401, ...),但没调 ctx.StopExecution(),控制流仍会进入下一个中间件甚至最终 handler,造成重复响应或业务逻辑误执行。
典型错误:JWT 验证失败后 ctx.StatusCode(401); ctx.JSON(...),末尾却还写了 ctx.Next() —— 这不会报错,但 handler 依然会被调用。
- 正确模式:校验失败 → 写响应 →
ctx.StopExecution(),且确保ctx.Next()在 if 分支外不被执行 -
ctx.StopExecution()和ctx.Abort()效果相同,但 Iris 没有Abort()方法,别搜错了 - 别依赖 HTTP 状态码判断是否该终止:Iris 不检查是否已写响应就放行
ctx.Next(),这跟 Gin 不同,得自己盯住
读取原始请求体要小心,Body 只能读一次且可能已被消费
签名验证、日志审计等场景需要原始字节流,但 ctx.ReadJSON()、ctx.FormValue()、甚至某些日志中间件都会提前读取并消耗 ctx.Request().Body。直接再读会得到空内容。
安全做法是在中间件开头用 io.ReadAll() 读一次,然后用 bytes.NewReader() 和 io.NopCloser() 重置 Body,保证后续 handler 仍可正常解析。
- 别用
ctx.GetBody():它返回的是 Iris 缓存的副本,不保证原始编码(比如 URL 解码可能已发生) - 如果启用了自动 JSON 解析中间件(如
iris.JSON),Body 很可能已被提前读取,此时ctx.Request().Body已为空 - 重置 Body 后,
ctx.ReadJSON()和ctx.PostValues()才能继续工作;否则它们会返回空或 error
路径参数和查询参数别混淆,ctx.Params().Get() ≠ ctx.URLParam()
中间件常需根据路径做放行或拦截(比如跳过 /health、拦截 /admin/*),这时必须准确提取路径片段。新手容易把 ctx.URLParam("id") 当成获取 /user/123 中的 123,其实它只读 ?id=123 这种 query string。
路径参数(如 /user/{id:uint64})必须用 ctx.Params().Get("id");query 参数才用 ctx.URLParam("id")。拼错 key 名也不会 panic,只会返回空字符串,极难排查。
- 路径参数名大小写敏感:路由定义
{ID},就得用ctx.Params().Get("ID"),写成"id"就取不到 - 类型转换推荐用
ctx.Params().GetInt64("id")等带校验的方法,避免手动strconv.ParseInt() - 若路径未定义参数(如
/user),ctx.Params().Get("id")返回空字符串,不会 panic —— 但你要主动检查是否为空


















