欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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)
}

Go 语言编程 — net/http

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)
    }
}

示例

实现原理

Go 语言编程 — net/http

Go 语言编程 — net/http

注册请求路由

监听请求

处理请求

支持 https

HTTP 客户端

HTTP 服务端

本文地址:https://blog.csdn.net/Jmilk/article/details/107475006

相关标签: Golang