
本文介绍如何利用 go 标准库 `net/http` 的中间件思想,在所有 http 处理器(handlers)执行前,统一运行预处理函数(如 ip 黑名单校验),无需修改每个路由逻辑。
在 Go Web 开发中,net/http 包本身不提供“全局中间件”概念,但其极简的 http.Handler 接口(仅需实现 ServeHTTP(http.ResponseWriter, *http.Request) 方法)天然支持链式封装——这正是实现“前置执行逻辑”的核心机制。
最简洁、推荐的做法是定义一个包装型处理器(wrapper handler),在调用下游 handler 前插入自定义检查逻辑。例如,实现 IP 黑名单拦截:
type IPChecker struct {
next http.Handler
}
func (c IPChecker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if isBlacklisted(r.RemoteAddr) {
http.Error(w, "Access denied: IP blocked", http.StatusForbidden)
return
}
c.next.ServeHTTP(w, r) // 放行,交由后续处理器处理
}使用时,只需将原始路由处理器(如 http.ServeMux 或 gorilla/mux.Router)作为 next 字段传入,并将其整体作为 ListenAndServe 的第二个参数:
mux := http.NewServeMux()
mux.HandleFunc("/api/users", userHandler)
mux.HandleFunc("/admin", adminHandler)
// ✅ 包装后启动服务
log.Fatal(http.ListenAndServe(":8080", IPChecker{next: mux}))⚠️ 注意事项: r.RemoteAddr 默认包含端口号(如 "192.168.1.100:54321"),实际黑名单校验时建议用 strings.Split(r.RemoteAddr, ":")[0] 提取纯 IP; 若应用部署在反向代理(如 Nginx、Cloudflare)后,应改用 r.Header.Get("X-Forwarded-For") 并做可信代理校验,避免伪造; 此模式完全兼容 Gorilla Mux、Chi、HttpRouter 等第三方路由器,因其本质仍是 http.Handler; 可叠加多个包装器(如 IPChecker{AuthChecker{mux}}),形成中间件链,但需注意顺序与错误短路逻辑。
这种基于组合而非继承的设计,体现了 Go “少即是多”的哲学——无需框架即可构建可复用、可测试、无侵入的前置处理能力。










