Go中HTTP收发核心是服务端(http.ServeMux+ListenAndServe)与客户端(http.Client+NewRequest)分工:服务端用HandleFunc注册处理器,响应JSON等;客户端需自定义Client设超时,正确处理Body读写与关闭。
在 Go 中用 net/http 发送和接收 HTTP 数据非常直接,核心在于理解服务端(http.ServeMux + http.ListenAndServe)和客户端(http.Client + http.NewRequest)两种角色的分工。
服务端主要靠注册处理器函数来响应不同路径的请求。Go 内置的 http.HandleFunc 是最简方式:
func(http.ResponseWriter, *http.Request)
http.ResponseWriter 用于写响应状态码、头、正文;*http.Request 包含所有请求信息(URL、Method、Header、Body、Form 等)示例:启动一个返回 JSON 的 /api/user 接口
package mainimport ( "encoding/json" "net/http" )
type User struct { ID int
json:"id"Name stringjson:"name"}func userHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(User{ID: 123, Name: "Alice"}) }
func main() { http.HandleFunc("/api/user", userHandler) http.ListenAndServe(":8080", nil) // 启动服务器 }
根据前端传来的数据格式,选择对应方式解析:
r.URL.Query().Get("key") 或 r.FormValue("key")(后者会自动调用 ParseForm)r.ParseForm(),再用 r.PostFormValue("field")
json.NewDecoder(r.Body).Decode(&v),注意 r.Body 只能读一次,需提前检查 Content-Type
io.ReadAll(r.Body),记得关闭或 defer r.Body.Close()
不要直接用 http.Get 这类快捷函数——它们用默认 client,无法设超时,容易阻塞。推荐显式创建带配置的 http.Client:
Timeout 防止请求无限挂起(例如网络故障时)Transport 控制连接复用、TLS 设置、代理等http.NewRequest 构造请求,手动设置 Header、Body(比如加 Authorization、发 JSON)示例:POST 一个 JSON 到远程 API
client := &http.Client{
Timeout: 5 * time.Second,
}
req, _ := http.NewRequest("POST", "https://api.example.com/data", strings.NewReader(`{"name":"Bob"}`))
req.Header.Set
("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Status: %s, Body: %s", resp.Status, string(body))
http.Request.Body 是 io.ReadCloser,必须 Close(),否则连接不释放,可能耗尽资源http.Error(w, msg, code) 快速返回错误响应,比手动写状态码更安全nil 作为 http.ListenAndServe 的第二个参数,应传入自定义 http.ServeMux 或 http.Handler 方便测试和扩展