Golang 的 net/http 包详细讲解(基于 Go 1.26+ 最新特性,2026 年最新)
net/http 是 Go 标准库中最重要、最常用的包之一。它同时提供了完整的 HTTP 客户端和服务器实现,无需任何第三方框架就能构建高性能、生产可用的 Web 服务、API、爬虫等。它的设计哲学是简洁、高并发(每个请求一个 goroutine)、零依赖、安全默认。
即使在 Gin、Echo、Fiber 等框架流行的情况下,底层依然都是 net/http。掌握它,你就能看懂所有框架的源码、写出更高效的代码、排查更深层的问题。
1. 包概述
import "net/http"
核心能力:
- 服务器端:
http.Server+ServeMux(路由)+Handler - 客户端端:
http.Client+Transport(传输层) - 协议支持:HTTP/1.1、HTTP/2(默认开启)、HTTP/3(需单独配置)
- 并发模型:天然支持 10w+ 并发(goroutine 轻量)
- 安全性:Go 1.25+ 新增
CrossOriginProtection防 CSRF
2. HTTP 服务器端(最常用部分)
2.1 最简单的服务器(Hello World)
package main
import (
"fmt"
"log"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}
func main() {
http.HandleFunc("/", hello) // 注册路由
log.Fatal(http.ListenAndServe(":8080", nil)) // 启动服务器
}
2.2 核心概念:Handler 与 HandlerFunc
Handler接口(核心):type Handler interface { ServeHTTP(w ResponseWriter, r *Request) }HandlerFunc是适配器:type HandlerFunc func(ResponseWriter, *Request) func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) }
所有路由最终都是 Handler。
2.3 路由器 ServeMux(重中之重!Go 1.22+ 大升级)
http.ServeMux 是内置路由器,Go 1.22 之前只能匹配路径前缀,Go 1.22+ 引入了现代路由特性:
新语法(强烈推荐):
mux := http.NewServeMux()
// 1. 方法匹配(GET/POST/PUT/DELETE/HEAD/PATCH/OPTIONS)
mux.HandleFunc("GET /users", listUsers)
mux.HandleFunc("POST /users", createUser)
mux.HandleFunc("GET /users/{id}", getUser) // {id} 是通配符
mux.HandleFunc("DELETE /users/{id}", deleteUser)
// 2. 通配符
// {name} 匹配一段(不含 /)
// {name...} 匹配剩余路径(catch-all)
mux.HandleFunc("GET /files/{filepath...}", serveFile)
// 3. 主机名匹配
mux.HandleFunc("example.com/", hostHandler)
// 4. 优先级规则(从高到低)
// 方法+精确路径 > 方法+通配符 > 无方法精确路径 > 无方法通配符
提取参数(Go 1.21+):
func getUser(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id") // 字符串,直接用
// id... 也是 PathValue("filepath")
fmt.Fprintf(w, "User ID: %s", id)
}
兼容老代码:设置环境变量 GODEBUG=httpmuxgo121=1 可恢复 Go 1.21 行为。
注册方式:
http.Handle(pattern, h Handler)http.HandleFunc(pattern, func(w, r))(最常用)- 自定义
mux := http.NewServeMux()→server.Handler = mux
2.4 http.Server 结构体(生产必用)
server := &http.Server{
Addr: ":8080",
Handler: mux, // 自定义 mux 或 nil(用 DefaultServeMux)
ReadTimeout: 10 * time.Second, // 读取请求超时
WriteTimeout: 10 * time.Second, // 写入响应超时
IdleTimeout: 120 * time.Second, // 空闲连接超时
MaxHeaderBytes: 1 << 20, // 头最大 1MB
TLSConfig: &tls.Config{}, // HTTPS 配置
// Go 1.24+ 新增
HTTP2: http.HTTP2Config{MaxConcurrentStreams: 1000},
}
server.ListenAndServe() // HTTP
server.ListenAndServeTLS("cert.pem", "key.pem") // HTTPS
优雅关闭(生产必须):
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
server.Shutdown(ctx) // 不再接收新请求,等待现有请求完成
3. Request 与 ResponseWriter 详解
Request 关键字段/方法
| 字段/方法 | 说明 | 常用场景 |
|---|---|---|
Method | “GET”, “POST” 等 | 判断方法 |
URL | *url.URL | 路径、查询参数 |
Header | http.Header (map) | 读写 Header |
Body | io.ReadCloser | 读取请求体 |
Context() | context.Context | 超时/取消 |
PathValue(name) | Go 1.22+ 通配符参数 | 路由参数 |
FormValue(key) | 自动 ParseForm,返回第一个值 | 表单 |
PostFormValue(key) | 只读 POST body | POST 表单 |
Cookie(name) | 获取 Cookie | 会话 |
ParseMultipartForm | 处理文件上传 | 大文件 |
读取 body(重要!只能读一次):
body, _ := io.ReadAll(r.Body)
defer r.Body.Close()
ResponseWriter 接口
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
使用技巧:
w.Header().Set("Content-Type", "application/json")w.WriteHeader(http.StatusOK)必须在Write前调用- 写完 Header 后仍可写 Trailer(
Trailer:前缀) - Go 1.20+
ResponseController可精细控制 Flush/Hijack/Deadline
4. 实用服务器功能
静态文件(Go 1.22+ 推荐):
mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServerFS(os.DirFS("./static"))))中间件(链式调用):
func Logging(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Printf("%s %s", r.Method, r.URL.Path) next.ServeHTTP(w, r) }) } mux.Handle("/", Logging(http.HandlerFunc(hello)))超时保护:
http.TimeoutHandler(handler, 5*time.Second, "timeout!")限流 body 大小:
r.Body = http.MaxBytesReader(w, r.Body, 1<<20) // 1MB
5. HTTP 客户端
5.1 核心:http.Client
client := &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
Jar: cookiejar.New(nil), // 自动管理 Cookie
}
永远不要用 http.DefaultClient 做生产(无超时、无配置)!
5.2 常用方法
resp, err := client.Get("https://example.com")
resp, err := client.Post("https://api.com", "application/json", bytes.NewReader(data))
resp, err := client.Do(req) // 最灵活
defer resp.Body.Close()
创建 Request(推荐带 Context):
req, _ := http.NewRequestWithContext(ctx, "POST", url, body)
req.Header.Set("Authorization", "Bearer xxx")
6. 高级特性与最佳实践(2026 年最新)
HTTP/2 & HTTP/3 配置(Go 1.24+)
server.HTTP2 = http.HTTP2Config{MaxConcurrentStreams: 250}防 CSRF(Go 1.25+)
cop := http.CrossOriginProtection{} cop.AddTrustedOrigin("https://trusted.com") mux.Handle("/", cop.Handler(myHandler))性能调优
- 复用
http.Client和Transport - 开启
GOMAXPROCS= CPU 核数 - 使用
pprof:http.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
- 复用
常见陷阱
- Body 只能读一次 → 用
io.NopCloser复制 - 忘记
defer resp.Body.Close() - 直接用
DefaultServeMux做复杂项目 - 未设置超时 → 容易被慢请求耗尽连接
- Body 只能读一次 → 用
7. 完整示例:RESTful API(推荐写法)
package main
import (
"encoding/json"
"net/http"
)
type User struct { ID string `json:"id"`; Name string `json:"name"` }
var users = map[string]User{}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
if u, ok := users[id]; ok {
json.NewEncoder(w).Encode(u)
return
}
http.Error(w, "not found", http.StatusNotFound)
})
mux.HandleFunc("POST /users", func(w http.ResponseWriter, r *http.Request) {
var u User
json.NewDecoder(r.Body).Decode(&u)
users[u.ID] = u
w.WriteHeader(http.StatusCreated)
})
server := &http.Server{Addr: ":8080", Handler: mux}
server.ListenAndServe()
}
总结:net/http 是 Go 最强大、最优雅的标准库之一。学透它,你就掌握了 Go Web 开发的 80%。
推荐阅读顺序:
- 官方文档:https://pkg.go.dev/net/http
- Go 1.22 路由增强博客:https://go.dev/blog/routing-enhancements
- 实际项目中直接用
http.Server + NewServeMux+ 中间件链
