Skip to content

Go http 包

Go 語言標准庫中的net/http包十分的優秀,提供了非常完善的 HTTP 客戶端與服務端的實現,僅通過幾行代碼就可以搭建一個非常簡單的 HTTP 服務器。

幾乎所有的 go 語言中的 web 框架,都是對已有的 http 包做的封裝與修改,因此,十分建議學習其他框架前先行掌握 http 包。

Get 示例

關於 Http 相關的知識這裡不再贅述,想要了解更多的話可以去百度。

go
func main() {
  resp, err := http.Get("https://baidu.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()
  content, err := io.ReadAll(resp.Body)
  fmt.Println(string(content))
}

通過直接調用 Http 包下的函數就可以發起簡單的請求,會返回一個指針與錯誤,調用過後必須將其手動關閉。

Post 示例

go
func main() {
   person := Person{
      UserId:   "120",
      Username: "jack",
      Age:      18,
      Address:  "usa",
   }

   json, _ := json.Marshal(person)
   reader := bytes.NewReader(json)

   resp, err := http.Post("https://golang.org", "application/json;charset=utf-8", reader)
   if err != nil {
      fmt.Println(err)
   }
   defer resp.Body.Close()
}

客戶端

一般情況下,我們都不會直接使用上述的方法,而且會自己配置一個客戶端來達到更加細致化的需求。這將會用到http.Client{}結構體,可提供的配置項總共有四個:

  • Transport:配置 Http 客戶端數據傳輸相關的配置項,沒有就采用默認的策略
  • Timeout:請求超時時間配置
  • Jar:Cookie 相關配置
  • CheckRedirect:重定向配置

簡單示例

go
func main() {
  client := &http.Client{}
  request, _ := http.NewRequest("GET", "https://golang.org", nil)
  resp, _ := client.Do(request)
  defer resp.Body.Close()
}

增加 header

go
func main() {
   client := &http.Client{}
   request, _ := http.NewRequest("GET", "https://golang.org", nil)
   request.Header.Add("Authorization","123456")
   resp, _ := client.Do(request)
   defer resp.Body.Close()
}

一些詳細的配置這裡不會做過多的贅述,還請自行了解。

服務端

對於 go 而言,創建一個 http 服務器只需要一行代碼。

第一個參數是監聽的地址,第二個參數是處理器,如果為空的話則使用默認的處理器。大多數情況下使用默認的處理器 DefaultServeMux 即可。

go
http.ListenAndServe("localhost:8080", nil)

自定義

當然也可以自定義配置一個服務端

go
func main() {
   server := &http.Server{
      Addr:              ":8080",
      Handler:           nil,
      TLSConfig:         nil,
      ReadTimeout:       0,
      ReadHeaderTimeout: 0,
      WriteTimeout:      0,
      IdleTimeout:       0,
      MaxHeaderBytes:    0,
      TLSNextProto:      nil,
      ConnState:         nil,
      ErrorLog:          nil,
      BaseContext:       nil,
      ConnContext:       nil,
   }
   server.ListenAndServe()
}

一些詳細的配置請自行了解。

路由

首先需要首先自定義一個結構體實現Handler接口中的ServeHTTP(ResponseWriter, *Request)方法,再調用http.handle()函數即可

go
func main() {
   http.Handle("/index", &MyHandler{})
   http.ListenAndServe(":8080", nil)
}

type MyHandler struct {
}

func (h *MyHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
   fmt.Println("my implement")
}

但是每一次都要自定義一個結構體將會十分的繁瑣,也可以直接http.handlerFunc函數,我們只需要寫處理函數即可,從而不用創建結構體。其內部是使用了適配器類型HandlerFunc,HandlerFunc 類型是一個適配器,允許將普通函數用作 HTTP 的處理器。如果 f 是具有適當簽名的函數,HandlerFunc(f)是調用 f 的 Handler。

go
func main() {
   http.HandleFunc("/index", func(responseWriter http.ResponseWriter, request *http.Request) {
      fmt.Println(responseWriter, "index")
   })
   http.ListenAndServe(":8080", nil)
}

ServerMux是核心結構體,實現了基本的方法,DefaultServeMux是的默認實例。

反向代理

http 包提供了開箱即用的反向代理功能

go
func main() {
   http.HandleFunc("/forward", func(writer http.ResponseWriter, request *http.Request) {
      director := func(request *http.Request) {
         request.URL.Scheme = "https"
         request.URL.Host = "golang.org"
         request.URL.Path = "index"
      }

      proxy := httputil.ReverseProxy{Director: director}
      proxy.ServeHTTP(writer, request)

   })

   http.ListenAndServe(":8080", nil)
}

上述代碼會將所有請求轉發到https://golang.org/index

Golang學習網由www.golangdev.cn整理維護