Go 语言 net/http模块的完备方法详解及示例

[复制链接]
发表于 2025-10-8 20:24:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
以下是 Go 语言 net/http 模块的完备方法详解及示例,涵盖全部核心功能

一、常量

常见的HTTP方法
变量名值备注MethodGetGETMethodHeadHEADMethodPostPOSTMethodPutPUTMethodPatchPATCHMethodDeletePATCHRFC 5789MethodDeleteDELETEMethodConnectCONNECTMethodOptionsOPTIONSMethodTraceTRACEIANA注册的HTTP状态代码
变量名值备注StatusContinue100// RFC 9110, 15.2.1StatusSwitchingProtocols101// RFC 9110, 15.2.2StatusProcessing102// RFC 2518, 10.1  \StatusEarlyHints103// RFC 8297 \StatusOK200// RFC 9110, 15.3.1 \StatusCreated201// RFC 9110, 15.3.2 \StatusAccepted202// RFC 9110, 15.3.3 \StatusNonAuthoritativeInfo203// RFC 9110, 15.3.4 \StatusNoContent204// RFC 9110, 15.3.5 \StatusResetContent205// RFC 9110, 15.3.6 \StatusPartialContent206// RFC 9110, 15.3.7 \StatusMultiStatus207// RFC 4918, 11.1 \StatusAlreadyReported208// RFC 5842, 7.1 \StatusIMUsed226// RFC 3229, 10.4.1 \StatusMultipleChoices300// RFC 9110, 15.4.1 \StatusMovedPermanently301// RFC 9110, 15.4.2 \StatusFound302// RFC 9110, 15.4.3 \StatusSeeOther303// RFC 9110, 15.4.4 \StatusNotModified304// RFC 9110, 15.4.5 \StatusUseProxy305// RFC 9110, 15.4.6 \StatusTemporaryRedirect307// RFC 9110, 15.4.8 \StatusPermanentRedirect308// RFC 9110, 15.4.9 \StatusBadRequest400// RFC 9110, 15.5.1 \StatusUnauthorized401// RFC 9110, 15.5.2 \StatusPaymentRequired402// RFC 9110, 15.5.3 \StatusForbidden403// RFC 9110, 15.5.4 \StatusNotFound404// RFC 9110, 15.5.5 \StatusMethodNotAllowed405// RFC 9110, 15.5.6 \StatusNotAcceptable406// RFC 9110, 15.5.7 \StatusProxyAuthRequired407// RFC 9110, 15.5.8 \StatusRequestTimeout408// RFC 9110, 15.5.9 \StatusConflict409// RFC 9110, 15.5.10 \StatusGone410// RFC 9110, 15.5.11 \StatusLengthRequired411// RFC 9110, 15.5.12 \StatusPreconditionFailed412// RFC 9110, 15.5.13 \StatusRequestEntityTooLarge413// RFC 9110, 15.5.14 \StatusRequestURITooLong414// RFC 9110, 15.5.15 \StatusUnsupportedMediaType415// RFC 9110, 15.5.16 \StatusRequestedRangeNotSatisfiable416// RFC 9110, 15.5.17 \StatusExpectationFailed417// RFC 9110, 15.5.18 \StatusTeapot418// RFC 9110, 15.5.19 (Unused) \StatusMisdirectedRequest421// RFC 9110, 15.5.20 \StatusUnprocessableEntity422// RFC 9110, 15.5.21 \StatusLocked423// RFC 4918, 11.3 \StatusFailedDependency424// RFC 4918, 11.4 \StatusTooEarly425// RFC 8470, 5.2. \StatusUpgradeRequired426// RFC 9110, 15.5.22 \StatusPreconditionRequired428// RFC 6585, 3 \StatusTooManyRequests429// RFC 6585, 4 \StatusRequestHeaderFieldsTooLarge431// RFC 6585, 5 \StatusUnavailableForLegalReasons451// RFC 7725, 3 \StatusInternalServerError500// RFC 9110, 15.6.1 \StatusNotImplemented501// RFC 9110, 15.6.2  \StatusBadGateway502// RFC 9110, 15.6.3 \StatusServiceUnavailable503// RFC 9110, 15.6.4 \StatusGatewayTimeout504// RFC 9110, 15.6.5 \StatusHTTPVersionNotSupported505// RFC 9110, 15.6.6 \StatusVariantAlsoNegotiates506// RFC 2295, 8.1 \StatusInsufficientStorage507// RFC 4918, 11.5 \StatusLoopDetected508// RFC 5842, 7.2 \StatusNotExtended510// RFC 2774, 7 \StatusNetworkAuthenticationRequired511// RFC 6585, 6 \变量名值备注DefaultMaxHeaderBytes1 << 20// 1 MB DefaultMaxHeaderBytes 是标头的最大答应巨细 在 HTTP 哀求中。 这可以通过设置 [Server.MaxHeaderBytes] 来覆盖。DefaultMaxIdleConnsPerHost2DefaultMaxIdleConnsPerHost 是 Transport 的 MaxIdleConnsPerHost 的TimeFormat“Mon, 02 Jan 2006 15:04:05 GMT”TimeFormat 是在 HTTP 中天生时间时利用的时间格式 头。这就像时间。RFC1123但将 GMT 硬编码为时间 区。要格式化的时间必须接纳 UTC 格式,以便将 Format (格式) 设置为 天生正确的格式。TrailerPrefix“Trailer:”TrailerPrefix 是 [ResponseWriter.Header] 映射键的把戏前缀 如果存在,则体现 Map 条目现实上是用于 相应尾部,而不是相应标头。前缀 在 ServeHTTP 调用完成后被剥离,值为 在拖车中发送。此机制仅实用于未知的拖车 在写入标头之前。如果拖车组是固定的 大概在写入 header 之前就知道,正常的 Go trailers 机制 是首选:https://pkg.go.dev/net/http#ResponseWriter https://pkg.go.dev/net/http#example-ResponseWriter-Trailers
二、变量

变量名值备注ErrNotSupported&rotocolError{“feature not supported”}特性不支持ErrUnexpectedTrailer&rotocolError{“trailer header without chunked transfer encoding”}已弃用: net/http 包中的任何内容都不再返回 ErrUnexpectedTrailer。调用方不应将错误与此变量举行比力。ErrMissingBoundary&rotocolError{“no multipart boundary param in Content-Type”}当哀求的 Content-Type 不包罗“boundary”参数时,Request.MultipartReader 会返回 ErrMissingBoundary。ErrNotMultipart&rotocolError{“request Content-Type isn’t multipart/form-data”}当哀求的 Content-Type 不是 multipart/form-data 时,Request.MultipartReader 会返回 ErrNotMultipart。ErrHeaderTooLong&rotocolError{“header too long”}已弃用: net/http 包中的任何内容都不再返回 ErrHeaderTooLong。调用方不应将错误与此变量举行比力。ErrShortBody&rotocolError{“entity body too short”}已弃用: net/http 包中的任何内容都不再返回 ErrShortBody。调用方不应将错误与此变量举行比力。ErrMissingContentLength&rotocolError{“missing ContentLength in HEAD response”}已弃用: net/http 包中的任何内容都不再返回 ErrMissingContentLength。调用方不应将错误与此变量举行比力。ErrBodyNotAllowederrors.New(“http: request method or response status code does not allow body”)当 HTTP 方法或相应代码不答应正文时,ResponseWriter.Write 调用会返回 ErrBodyNotAllowed。ErrHijackederrors.New(“http: connection has been hijacked”)当底层毗连利用 Hijacker 接口被挟制时,ErrHijacked 由 ResponseWriter.Write 调用返回。对被挟制的毗连举行零字节写入将返回 ErrHijacked,而不会产生任何其他副作用。ErrContentLengtherrors.New(“http: wrote more than the declared Content-Length”)当 Handler 利用声明的巨细设置 Content-Length 相应标头,然后实验写入比声明的字节数更多的字节时,ResponseWriter.Write 调用会返回 ErrContentLength。ErrWriteAfterFlusherrors.New(“unused”)已弃用:net/http 包中的任何内容都不再返回 ErrWriteAfterFlush。调用方不应将错误与此变量举行比力。HTTP 服务器利用的错误。
变量名值备注ServerContextKey&contextKey{“http-server”}ServerContextKey 是上下文键。它可以在 HTTP 处理处罚步伐中利用 Context.Value 来访问启动处理处罚步伐的服务器。关联的值将为 *Server 范例。LocalAddrContextKey&contextKey{“local-addr”}LocalAddrContextKey 是上下文键。它可以在具有 Context.Value 的 HTTP 处理处罚步伐中利用,以访问毗连到达的本地所在。关联的值将为 net 范例。所在。DefaultClient&Client{}DefaultClient 是默认 Client,由 Get、Head 和 Post 利用。DefaultServeMux&defaultServeMuxDefaultServeMux 是 Serve 利用的默认 ServeMux。ErrAbortHandlererrors.New(“net/http: abort Handler”)ErrAbortHandler 是用于中断处理处罚步伐的 sentinel panic 值。 固然来自 ServeHTTP 的任何 panic 都会中断对客户端的相应, 利用 ErrAbortHandler 举行 panic 也会克制堆栈的日记记载 trace 到服务器的错误日记。ErrBodyReadAfterCloseerrors.New(“http: invalid Read on closed Body”)ErrBodyReadAfterClose 在正文关闭后读取哀求或相应正文时返回。这通常发生在身材 在 HTTP 处理处罚步伐对其 ResponseWriter 调用 WriteHeader 或 Write 之后读取。ErrHandlerTimeouterrors.New(“http: Handler timeout”)ErrHandlerTimeout 在 ResponseWriter Write 调用时返回 在已超时的处理处罚步伐中。ErrLineTooLonginternal.ErrLineTooLong读取哀求或相应正文时返回 ErrLineTooLong 利用格式错误的分块编码。ErrMissingFileerrors.New(“http: no such file”)当提供的文件字段名称时,FormFile 会返回 ErrMissingFile 要么不存在于哀求中,要么不是 file 字段。ErrNoCookieerrors.New(“http: named cookie not present”)当找不到 Cookie 时,Request 的 Cookie 方法会返回 ErrNoCookie。ErrNoLocationerrors.New(“http: no Location header in response”)ErrNoLocation 由 Response.Location 方法返回 当不存在 Location 标头时。ErrSchemeMismatcherrors.New(“http: server gave HTTP response to HTTPS client”)当服务器向 HTTPS 客户端返回 HTTP 相应时,将返回 ErrSchemeMismatch。ErrServerClosederrors.New(“http: Server closed”)ErrServerClosed 由 Server.Serve、ServeTLS、ListenAndServe、 和 ListenAndServeTLS 方法。ErrSkipAltProtocolerrors.New(“net/http: skip alternate protocol”)ErrSkipAltProtocol 是由 Transport.RegisterProtocol 界说的 sentinel 错误值。ErrUseLastResponseerrors.New(“net/http: use last response”)ErrUseLastResponse 可以通过 Client.CheckRedirect 钩子返回给 控制重定向的处理处罚方式。如果返回,则为下一个哀求 未发送,而且迩来的相应将返回其正文 未关闭。NoBodynoBody{}NoBody 是 io。ReadCloser 的 URL 中。读取始终返回 EOF 和 Close 始终返回 nil。它可以在传出客户端中利用 哀求显式体现哀求具有零字节。 但是,另一种方法是简朴地将 [Request.Body] 设置为 nil。三.、HTTP 服务器功能方法

3.1 创建根本服务器
  1. package main
  2. import (
  3.         "fmt"
  4.         "net/http"
  5. )
  6. func helloHandler(w http.ResponseWriter, r *http.Request) {
  7.         fmt.Fprintf(w, "Hello, World!")
  8. }
  9. func main() {
  10.         http.HandleFunc("/hello", helloHandler)
  11.         fmt.Println("Server starting on port 8080...")
  12.         http.ListenAndServe(":8080", nil)
  13. }
复制代码
3.2 路由处理处罚

http.HandleFunc
  1. http.HandleFunc("/greet", func(w http.ResponseWriter, r *http.Request) {
  2.         name := r.URL.Query().Get("name")
  3.         if name == "" {
  4.                 name = "Guest"
  5.         }
  6.         fmt.Fprintf(w, "Hello, %s!", name)
  7. })
复制代码
http.Handle (利用自界说处理处罚器)
  1. type greetingHandler struct{}
  2. func (h *greetingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  3.         fmt.Fprintf(w, "Welcome to the greeting page!")
  4. }
  5. func main() {
  6.         http.Handle("/greeting", &greetingHandler{})
  7.         http.ListenAndServe(":8080", nil)
  8. }
复制代码
3.3 利用 ServeMux 举行多路复用
  1. func main() {
  2.         mux := http.NewServeMux()
  3.        
  4.         mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  5.                 fmt.Fprintf(w, "Home Page")
  6.         })
  7.        
  8.         mux.HandleFunc("/about", func(w http.ResponseWriter, r *http.Request) {
  9.                 fmt.Fprintf(w, "About Page")
  10.         })
  11.        
  12.         http.ListenAndServe(":8080", mux)
  13. }
复制代码
3.4 中心件模式
  1. func loggingMiddleware(next http.Handler) http.Handler {
  2.         return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  3.                 fmt.Printf("%s %s\n", r.Method, r.URL.Path)
  4.                 next.ServeHTTP(w, r)
  5.         })
  6. }
  7. func main() {
  8.         mux := http.NewServeMux()
  9.         mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  10.                 fmt.Fprintf(w, "Home Page")
  11.         })
  12.        
  13.         http.ListenAndServe(":8080", loggingMiddleware(mux))
  14. }
复制代码
3.5 文件服务器
  1. func main() {
  2.         // 静态文件服务
  3.         fs := http.FileServer(http.Dir("static/"))
  4.         http.Handle("/static/", http.StripPrefix("/static/", fs))
  5.        
  6.         http.ListenAndServe(":8080", nil)
  7. }
复制代码
四、 HTTP 客户端功能

4.1 发送 GET 哀求
  1. func main() {
  2.         resp, err := http.Get("https://api.example.com/data")
  3.         if err != nil {
  4.                 fmt.Println("Error:", err)
  5.                 return
  6.         }
  7.         defer resp.Body.Close()
  8.        
  9.         body, err := io.ReadAll(resp.Body)
  10.         if err != nil {
  11.                 fmt.Println("Error reading response:", err)
  12.                 return
  13.         }
  14.        
  15.         fmt.Println(string(body))
  16. }
复制代码
4.2 发送 POST 哀求
  1. func main() {
  2.         payload := strings.NewReader(`{"name":"John","age":30}`)
  3.         resp, err := http.Post(
  4.                 "https://api.example.com/users",
  5.                 "application/json",
  6.                 payload,
  7.         )
  8.         if err != nil {
  9.                 fmt.Println("Error:", err)
  10.                 return
  11.         }
  12.         defer resp.Body.Close()
  13.        
  14.         // 处理响应...
  15. }
复制代码
4.3 自界说哀求 (利用 http.NewRequest)
  1. func main() {
  2.         payload := strings.NewReader(`{"query":"search term"}`)
  3.        
  4.         req, err := http.NewRequest(
  5.                 "POST",
  6.                 "https://api.example.com/search",
  7.                 payload,
  8.         )
  9.         if err != nil {
  10.                 fmt.Println("Error creating request:", err)
  11.                 return
  12.         }
  13.        
  14.         req.Header.Add("Content-Type", "application/json")
  15.         req.Header.Add("Authorization", "Bearer abc123")
  16.        
  17.         client := &http.Client{}
  18.         resp, err := client.Do(req)
  19.         if err != nil {
  20.                 fmt.Println("Error sending request:", err)
  21.                 return
  22.         }
  23.         defer resp.Body.Close()
  24.        
  25.         // 处理响应...
  26. }
复制代码
4.4 处理处罚 JSON 相应
  1. type User struct {
  2.         ID    int    `json:"id"`
  3.         Name  string `json:"name"`
  4.         Email string `json:"email"`
  5. }
  6. func main() {
  7.         resp, err := http.Get("https://api.example.com/users/1")
  8.         if err != nil {
  9.                 fmt.Println("Error:", err)
  10.                 return
  11.         }
  12.         defer resp.Body.Close()
  13.        
  14.         var user User
  15.         if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
  16.                 fmt.Println("Error decoding JSON:", err)
  17.                 return
  18.         }
  19.        
  20.         fmt.Printf("User: %+v\n", user)
  21. }
复制代码
五、 高级功能

5.1 设置超时
  1. func main() {
  2.         client := &http.Client{
  3.                 Timeout: 10 * time.Second,
  4.         }
  5.        
  6.         resp, err := client.Get("https://api.example.com/slow-endpoint")
  7.         if err != nil {
  8.                 fmt.Println("Error:", err)
  9.                 return
  10.         }
  11.         defer resp.Body.Close()
  12.        
  13.         // 处理响应...
  14. }
复制代码
5.2 处理处罚 Cookie

服务器设置 Cookie
  1. func setCookieHandler(w http.ResponseWriter, r *http.Request) {
  2.         cookie := &http.Cookie{
  3.                 Name:  "session_id",
  4.                 Value: "abc123",
  5.                 Path:  "/",
  6.                 MaxAge: 3600,
  7.         }
  8.         http.SetCookie(w, cookie)
  9.         fmt.Fprintf(w, "Cookie set!")
  10. }
复制代码
客户端发送 Cookie
  1. func main() {
  2.         req, err := http.NewRequest("GET", "https://api.example.com/protected", nil)
  3.         if err != nil {
  4.                 fmt.Println("Error:", err)
  5.                 return
  6.         }
  7.        
  8.         cookie := &http.Cookie{
  9.                 Name:  "session_id",
  10.                 Value: "abc123",
  11.         }
  12.         req.AddCookie(cookie)
  13.        
  14.         client := &http.Client{}
  15.         resp, err := client.Do(req)
  16.         // 处理响应...
  17. }
复制代码
5.3 HTTPS 服务器
  1. func main() {
  2.         http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  3.                 fmt.Fprintf(w, "Secure Hello World!")
  4.         })
  5.        
  6.         err := http.ListenAndServeTLS(
  7.                 ":443",
  8.                 "server.crt",
  9.                 "server.key",
  10.                 nil,
  11.         )
  12.         if err != nil {
  13.                 fmt.Println("Error starting server:", err)
  14.         }
  15. }
复制代码
5.4 处理处罚文件上传
  1. func uploadHandler(w http.ResponseWriter, r *http.Request) {
  2.         if r.Method != "POST" {
  3.                 http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
  4.                 return
  5.         }
  6.        
  7.         // 解析 multipart 表单,限制上传大小为 10MB
  8.         err := r.ParseMultipartForm(10 << 20)
  9.         if err != nil {
  10.                 http.Error(w, err.Error(), http.StatusBadRequest)
  11.                 return
  12.         }
  13.        
  14.         file, handler, err := r.FormFile("myFile")
  15.         if err != nil {
  16.                 http.Error(w, err.Error(), http.StatusBadRequest)
  17.                 return
  18.         }
  19.         defer file.Close()
  20.        
  21.         // 创建目标文件
  22.         dst, err := os.Create(handler.Filename)
  23.         if err != nil {
  24.                 http.Error(w, err.Error(), http.StatusInternalServerError)
  25.                 return
  26.         }
  27.         defer dst.Close()
  28.        
  29.         // 复制文件内容
  30.         if _, err := io.Copy(dst, file); err != nil {
  31.                 http.Error(w, err.Error(), http.StatusInternalServerError)
  32.                 return
  33.         }
  34.        
  35.         fmt.Fprintf(w, "File uploaded successfully: %s", handler.Filename)
  36. }
  37. func main() {
  38.         http.HandleFunc("/upload", uploadHandler)
  39.         http.ListenAndServe(":8080", nil)
  40. }
复制代码
六、 告急范例和接口

6.1 http.ResponseWriter

用于构造 HTTP 相应,告急方法:
  1. func handler(w http.ResponseWriter, r *http.Request) {
  2.         // 设置状态码
  3.         w.WriteHeader(http.StatusOK)
  4.        
  5.         // 设置响应头
  6.         w.Header().Set("Content-Type", "application/json")
  7.         w.Header().Add("X-Custom-Header", "value")
  8.        
  9.         // 写入响应体
  10.         fmt.Fprintf(w, `{"status":"ok"}`)
  11. }
复制代码
6.2 http.Request

包罗客户端哀求的全部信息:
  1. func handler(w http.ResponseWriter, r *http.Request) {
  2.         // 请求方法
  3.         method := r.Method
  4.        
  5.         // URL 信息
  6.         path := r.URL.Path
  7.         query := r.URL.Query().Get("param")
  8.        
  9.         // 请求头
  10.         contentType := r.Header.Get("Content-Type")
  11.        
  12.         // 请求体
  13.         body, err := io.ReadAll(r.Body)
  14.         if err != nil {
  15.                 http.Error(w, err.Error(), http.StatusBadRequest)
  16.                 return
  17.         }
  18.        
  19.         // 表单数据
  20.         formValue := r.FormValue("key")
  21.        
  22.         // 打印一些信息
  23.         fmt.Printf("Method: %s, Path: %s, Query: %s\n", method, path, query)
  24.         fmt.Printf("Content-Type: %s, Body: %s, FormValue: %s\n", contentType, body, formValue)
  25. }
复制代码
七、 实用工具函数

7.1 http.StripPrefix
  1. func main() {
  2.         // 将 /static/ 前缀去掉后再查找文件
  3.         http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("assets"))))
  4.         http.ListenAndServe(":8080", nil)
  5. }
复制代码
7.2 http.Redirect
  1. func redirectHandler(w http.ResponseWriter, r *http.Request) {
  2.         http.Redirect(w, r, "https://example.com/new-location", http.StatusMovedPermanently)
  3. }
复制代码
7.3 http.NotFound
  1. func handler(w http.ResponseWriter, r *http.Request) {
  2.         if r.URL.Path != "/valid-path" {
  3.                 http.NotFound(w, r)
  4.                 return
  5.         }
  6.         fmt.Fprintf(w, "Valid path")
  7. }
复制代码
总结

net/http 包提供了构建 HTTP 客户端和服务器的完备工具集。通过上面的示例,我们可以看到:

  • 创建 HTTP 服务器非常简朴,只需几行代码
  • 提供了机动的路由处理处罚机制
  • 支持中心件模式,方便扩展功能
  • 客户端 API 简便但功能强大
  • 内置支持 HTTPS、文件上传、Cookie 等常见功能
对于更高级的需求,可以联合第三方路由库(如 gorilla/mux)或框架(如 Gin、Echo)利用,但标准库的 net/http 已经可以大概满足大多数根本需求。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表