Go 语言编程 — net/http
程序员文章站
2022-06-19 10:23:01
目录文章目录目录net/httpnet/http...
目录
net/http
HTTP 是典型的 C/S 架构,客户端和服务端面对的都是双向的 HTTP 请求与响应,客户端构建请求并等待响应,服务端处理请求并返回响应。
Golang 的 net/http 标准库同时封装了 HTTP 客户端和服务端的实现。
官方文档:
- 英文:https://golang.org/pkg/net/http/
- 中文:https://cloud.tencent.com/developer/section/1143633
为了支持更好的扩展性,还引入了 http.RoundTripper 和 http.Handler 两个接口。
- http.Handler(请求处理程序):主要用于作为 HTTP 服务器响应客户端的 request。实现了处理 HTTP 请求的逻辑,处理的过程中会调用 http.ResponseWriter 接口的方法来构造一个相应的 HTTP 响应。
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
- http.ResponseWriter(响应编写器):提供了三个接口 Header、Write 和 WriteHeader 分别用于获取 HTTP 响应、将数据写入负载(Payload)和响应头(Header)。
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
- http.RoundTripper:用来表示执行 HTTP 请求的接口,调用者将 request 对象作为参数传入,就可以获取对应的 response 或 error。是一种特殊的调用方式,谓之 “往返者”。
type RoundTripper interface {
RoundTrip(*Request) (*Response, error)
}
HTTP 客户端
net/http 为客户端提供了 Get、Head、Post 和 PostForm 函数来发起 HTTP/HTTPS 请求。
示例
- 发出一个简单的 http.Get 请求:
package main
import (
"bytes"
"fmt"
"log"
"net/http"
"reflect"
)
func main() {
resp, err := http.Get("http://www.baidu.com")
if err != nil {
// handle error
log.Println(err)
return
}
defer resp.Body.Close()
headers := resp.Header
for k, v := range headers {
fmt.Printf("k=%v, v=%v\n", k, v)
}
fmt.Printf("resp status %s,statusCode %d\n", resp.Status, resp.StatusCode)
fmt.Printf("resp Proto %s\n", resp.Proto)
fmt.Printf("resp content length %d\n", resp.ContentLength)
fmt.Printf("resp transfer encoding %v\n", resp.TransferEncoding)
fmt.Printf("resp Uncompressed %t\n", resp.Uncompressed)
fmt.Println(reflect.TypeOf(resp.Body)) // *http.gzipReader
buf := bytes.NewBuffer(make([]byte, 0, 512))
length, _ := buf.ReadFrom(resp.Body)
fmt.Println(len(buf.Bytes()))
fmt.Println(length)
fmt.Println(string(buf.Bytes()))
}
- 使用 http.Post 或 http.PostForm 发出 POST 请求:
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
body_json_str := "{\"action\":20}"
res, err := http.Post("http://xxx.com", "application/json;charset=utf-8",
bytes.NewBuffer([]byte(body_json_str)))
if err != nil {
fmt.Println("Fatal error ", err.Error())
}
defer res.Body.Close()
content, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("Fatal error ", err.Error())
}
fmt.Println(string(content))
}
- http.PostForm:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
func main() {
postParam := url.Values{
"mobile": {"xxxxxx"},
"isRemberPwd": {"1"},
}
resp, err := http.PostForm("http://www.maimaiche.com/loginRegister/login.do", postParam)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
- 使用 http.NewRequest 来创建 request 对象,再通过 http.Client 执行这个 request 对象:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
func main() {
v := url.Values{}
v.Set("username", "xxxx")
v.Set("password", "xxxx")
body := ioutil.NopCloser(strings.NewReader(v.Encode()))
req, err := http.NewRequest("POST", "http://xxx.com/logindo", body)
if err != nil {
fmt.Println("Fatal error ", err.Error())
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded;param=value")
client := &http.Client{}
resp, err := client.Do(req)
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Fatal error ", err.Error())
}
fmt.Println(string(content))
}
- 客户端忽略 TLS 证书认证:
package main
import (
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
seedUrl := "https://www.douban.com/"
resp, err := client.Get(seedUrl)
if err != nil {
fmt.Errorf("get https://www.douban.com/ error")
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Errorf("get https://www.douban.com/ error")
panic(err)
}
fmt.Printf("%s\n", body)
}
实现原理
HTTP 服务端
package main
import (
"fmt"
"net/http"
)
func indexHandler(w http.ResponseWriter, request *http.Request) {
fmt.Fprintln(w, "Hello World.")
}
func main() {
http.HandleFunc("/", indexHandler)
err := http.ListenAndServe("127.0.0.1:80", nil)
if err != nil {
fmt.Println("ListenAndServe: ", err)
}
}
示例
实现原理
注册请求路由
监听请求
处理请求
支持 https
HTTP 客户端
HTTP 服务端
本文地址:https://blog.csdn.net/Jmilk/article/details/107475006