iris.compression不能在控制器中调用,因其是全局中间件,须在app.listen()前通过app.use()注册;控制器执行时响应头已开始写入,此时启用无效。

iris.Compression 不作用于 MVC 控制器内部,它只对整个 HTTP 响应体生效,且必须在 app := iris.Default() 或 iris.New() 之后、app.Listen() 之前启用——控制器本身不负责开启或关闭压缩。
为什么不能在控制器里调用 iris.Compression
该函数是全局中间件注册行为,返回一个 iris.Handler,需通过 app.Use() 或 app.UseGlobal() 挂载。控制器方法(如 Get()、PostCreate())运行时已处于请求处理中段,此时再试图“开启压缩”毫无意义——响应头早已开始写入,压缩器无法回溯修改。
- 常见错误现象:在控制器方法里写
iris.Compression(iris.Gzip),编译能过但完全无效,响应仍是明文 - 压缩是否生效,只取决于请求头
Accept-Encoding: gzip是否存在 + 全局中间件是否已注册 + 响应体大小是否超过默认阈值(1KB) - 如果你用的是
iris.Default(),它内部已自动启用了iris.Compression,无需额外操作
正确启用位置:在 main() 函数的路由注册前
无论你用 iris.New() 还是 iris.Default(),压缩中间件都必须在 MVC 应用挂载前注入:
func main() {
app := iris.New()
// ✅ 正确:全局启用 Gzip 压缩
app.Use(iris.Compression(iris.Gzip))
// 注册 MVC 路由
mvcApp := mvc.New(app.Party("/api"))
mvcApp.Handle(new(UserController))
app.Listen(":8080")
}
- 若用
iris.Default(),这一步可省略——它等价于iris.New().Use(recoverer, logger, compression) - 不要在
mvc.Configure回调里调用app.Use(),虽然语法允许,但语义混乱且易被覆盖 - 压缩对 JSON 响应有效,但对小响应(如
{"code":200})默认不压缩,可传入iris.GzipWithLevel(9)强制高压缩,但会增加 CPU 开销
验证压缩是否实际生效
别只看代码有没有写,要抓包确认:
- 用
curl -H "Accept-Encoding: gzip" -I http://localhost:8080/api/users查看响应头是否有Content-Encoding: gzip - 对比未带
Accept-Encoding头的请求,响应体长度应明显变小(可用curl -w "%{size_download}"测) - 如果返回
404或空响应,说明 MVC 路由根本没注册成功,压缩配置再对也白搭——先确保app.Party()和mvc.Handle()配对正确
真正容易被忽略的是:压缩只影响响应体,不影响控制器逻辑里的任何判断或错误处理;如果你在控制器里用 ctx.StopWithStatus() 提前终止,且没手动设置 Content-Encoding,那这部分响应也不会被压缩——因为中间件链已在 StopWithStatus 后跳过后续环节。











