Go HTTP中间件是接收并返回http.Handler的函数,通过闭包在原handler前后插入逻辑;需调用next.ServeHTTP以确保链式执行,顺序影响执行流程,配置应作为参数传入避免共享,panic恢复中间件须置于最外层。

什么是 Go HTTP 中间件
Go 的中间件本质是函数套函数:接收一个 http.Handler,返回一个新的 http.Handler,在调用原 handler 前后插入逻辑。它不是框架内置概念,而是基于 http.Handler 接口和闭包的自然延伸。
最简中间件写法(日志示例)
核心是实现 func(http.Handler) http.Handler 签名。注意别漏掉 next.ServeHTTP(w, r),否则请求就断了。
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("Started %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r) // 必须调用,否则下游 handler 不会执行
log.Printf("Completed %s %s", r.Method, r.URL.Path)
})
}
使用时链式包装:
handler := http.HandlerFunc(yourHandler)
handler = loggingMiddleware(handler)
handler = authMiddleware(handler) // 可叠加多个
http.ListenAndServe(":8080", handler)
带参数的中间件(如允许跨域)
中间件本身可以接受配置参数,返回“中间件工厂函数”。常见错误是把配置写死在闭包外,导致所有实例共享同一份配置。
Huawei LiteOS是华为面向物联网领域开发的一个基于实时内核的轻量级操作系统。本项目属于华为物联网操作系统Huawei LiteOS源码,现有基础内核支持任务管理、内存管理、时间管理、通信机制、中断管理、队列管理、事件管理、定时器等操作系统基础组件,更好地支持低功耗场景,支持tickless机制,支持定时器对齐。 同时提供端云协同能力,集成了LwM2M、CoAP、mbedtls、LwIP全
立即学习“go语言免费学习笔记(深入)”;
-
allowedOrigins应作为参数传入,而非全局变量 - 每个
CORS()调用返回独立的中间件实例 - 注意
w.Header().Set()必须在next.ServeHTTP之前设置响应头,否则可能被覆盖
func CORS(allowedOrigins []string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
if len(allowedOrigins) == 0 || contains(allowedOrigins, origin) {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
}
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
}
func contains(slice []string, s string) bool {
for _, v := range slice {
if v == s {
return true
}
}
return false
}
中间件顺序很重要
中间件从外到内执行:第一个包装的最先运行,最后一个包装的最后运行(但它的前置逻辑在 next.ServeHTTP 前,后置逻辑在之后)。比如:
-
loggingMiddleware(authMiddleware(handler)):先打日志 → 再鉴权 → 再执行 handler → 再打完成日志 - 如果鉴权失败,
next.ServeHTTP不会被调用,后续中间件和 handler 都不会执行 - panic 恢复中间件必须放在最外层,才能捕获所有内层 panic
容易忽略的是:中间件内部的 http.Error 或直接写 w.WriteHeader 后再调用 next.ServeHTTP,可能导致重复写 header 报错 http: multiple response.WriteHeader calls。









