这是我参与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
}