Go中的http

159 阅读3分钟

这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战

http

Go语言中的net/http包内置了HTTP服务端和客户端的实现

HTTP协议

HTTP - Hyper Text Transfer Protocol, 超文本传输协议

http/request.go

客户端向服务端发送一个请求, 必须创建一个request实例, 里面包含请求时设置的Headers信息, Cookies信息, 请求方式, 请求地址以及请求参数等

http/response.go

服务端向客户端发出的响应信息, 用来对客户端的请求作出响应, 可以设置响应的Headers, 响应状态以及响应信息等

http/client.go

客户端, 用来发送request请求给服务端. 可以使用Get方法, Post方法或者PostForm方法进行服务端的请求

http/server.go

服务端, 用来接收客户端发送的request请求, 可以用ListenAndServe进行地址的监听, 也可以从请求中获取请求参数, 例如: Headers, Cookies, Body等

// 这个函数用来监听addr网络地址, 然后调用handler来处理连接请求
func ListenAndServe(addr string, handler Handler) error {
   server := &Server{Addr: addr, Handler: handler}
   return server.ListenAndServe()
}

Get请求及响应

客户端

// 创建一个http.Client结构体实例
client := &http.Client{}

// 发送一个get请求
resp, err := client.Get("https://www.so.com/")
if err != nil {
   fmt.Println("client get failed: ", err)
   return
}

// 在得到响应后, 还需要关闭响应body
defer func() {
   fmt.Println("body closed!")
   resp.Body.Close()
}()

// 获取响应体里的内容
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))

服务端

// 不带参数的Get请求响应
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
   _, err := w.Write([]byte("ok"))
   if err != nil {
      fmt.Println("write failed: ", err)
      return
   }
})

带参数的Get请求及响应

客户端

// 创建一个http.Client结构体实例
client := &http.Client{}

// 请求地址
urlStr := "http://127.0.0.1:1000/login"

// 请求参数
data := url.Values{}
data.Set("username", "tianming")
data.Set("password", "456")

parseUrl, err := url.ParseRequestURI(urlStr)
if err != nil {
   fmt.Println("parse url failed: ", err)
   return
}

// 查看编码后的url
fmt.Println(parseUrl)

// 将请求参数进行url编码
parseUrl.RawQuery = data.Encode()

// 查看编码后的url
fmt.Println(parseUrl.String())

// 发送一个get请求
resp, err := client.Get(parseUrl.String())
if err != nil {
   fmt.Println("client get failed: ", err)
   return
}

// 在得到响应后, 还需要关闭响应body
defer func() {
   fmt.Println("body closed!")
   resp.Body.Close()
}()

// 获取响应体里的内容
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))

服务端

// 带参数的Get请求
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
   // 关闭body
   defer func() {
      fmt.Println("req body closed!")
      r.Body.Close()
   }()

   // 从request获取URL
   url := r.URL

   // 从URL中获取参数
   data := url.Query()
   username := data.Get("username")
   password := data.Get("password")

   // 打印参数
   fmt.Println("username: ", username, ", password: ", password)

   // 向客户端响应数据
   _, err := w.Write([]byte("ok"))
   if err != nil {
      fmt.Println("write failed: ", err)
      return
   }
})

Post请求及响应

客户端

c := &http.Client{}

// 设置post请求的contentType
contentType := "application/json"

data := `{"name":"dasiming", "password":"222"}`

// 设置post请求的body
body := strings.NewReader(data)

// 发送一个post请求
resp, err := c.Post("http://127.0.0.1:1000/postLogin", contentType, body)
if err != nil {
   fmt.Println("client post failed:", err)
   return
}

// 关闭body
defer func() {
   fmt.Println("resp body closed!")
   resp.Body.Close()
}()

// 读取服务端响应数据
res, err := ioutil.ReadAll(resp.Body)
if err != nil {
   fmt.Println("io read failed: ", err)
   return
}
fmt.Println(string(res))

服务端

// 带参数的post请求 application/json
http.HandleFunc("/postLogin", func(w http.ResponseWriter, r *http.Request) {
   // 关闭body
   defer func() {
      fmt.Println("post request body closed!")
      r.Body.Close()
   }()

   // 获取参数
   // application/json 方式请求
   data, _ := ioutil.ReadAll(r.Body)
   fmt.Println("body: ", string(data))

   // 向客户端响应数据
   _, err := w.Write([]byte("post request succeed!"))
   if err != nil {
      fmt.Println("write failed: ", err)
      return
   }
})

PostForm请求及响应

客户端

c := http.Client{}
// 数据会经过url编码后, 作为请求的body传递
data := url.Values{}
data.Set("username", "shaosiming")
data.Set("password", "18")

// 发送一个表单请求
resp, err := c.PostForm("http://127.0.0.1:1000/formLogin", data)
if err != nil {
   fmt.Println("client post form failed:", err)
   return
}

// 关闭body
defer func() {
   fmt.Println("resp body closed!")
   resp.Body.Close()
}()

// 读取从服务端返回的数据
res, err := ioutil.ReadAll(resp.Body)
if err != nil {
   fmt.Println("io read failed: ", err)
   return
}
fmt.Println(string(res))

服务端

// PostForm请求
http.HandleFunc("/formLogin", func(w http.ResponseWriter, r *http.Request) {
   // 关闭body
   defer func() {
      fmt.Println("form request body closed!")
      r.Body.Close()
   }()

   // 获取参数
   // PostForm 方式请求
   username := r.PostFormValue("username")
   password := r.PostFormValue("password")
   fmt.Println("PostForm: username: ", username, "password: ", password)

   // 向客户端响应数据
   _, err := w.Write([]byte("form request succeed!"))
   if err != nil {
      fmt.Println("write failed: ", err)
      return
   }
})

开启服务端地址监听

在服务端开发一个地址为:127.0.0.1, 端口为1000监听服务

// 服务端是监听地址
err := http.ListenAndServe("127.0.0.1:1000", nil)
if err != nil {
   fmt.Println("listen failed: ", err)
   return
}