Golang net/http 库日常 http 请求操作

http.Server{} 参数讲解

type Server struct {
    Addr           string        // 监听的TCP地址,如果为空字符串会使用":http"
    Handler        Handler       // 调用的处理器,如为nil会调用http.DefaultServeMux
    ReadTimeout    time.Duration // 请求的读取操作在超时前的最大持续时间
    WriteTimeout   time.Duration // 回复的写入操作在超时前的最大持续时间
    MaxHeaderBytes int           // 请求的头域最大长度,如为0则用DefaultMaxHeaderBytes
    TLSConfig      *tls.Config   // 可选的TLS配置,用于ListenAndServeTLS方法
    // TLSNextProto(可选地)指定一个函数来在一个NPN型协议升级出现时接管TLS连接的所有权。
    // 映射的键为商谈的协议名;映射的值为函数,该函数的Handler参数应处理HTTP请求,
    // 并且初始化Handler.ServeHTTP的*Request参数的TLS和RemoteAddr字段(如果未设置)。
    // 连接在函数返回时会自动关闭。
    TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
    // ConnState字段指定一个可选的回调函数,该函数会在一个与客户端的连接改变状态时被调用。
    // 参见ConnState类型和相关常数获取细节。
    ConnState func(net.Conn, ConnState)
    // ErrorLog指定一个可选的日志记录器,用于记录接收连接时的错误和处理器不正常的行为。
    // 如果本字段为nil,日志会通过log包的标准日志记录器写入os.Stderr。
    ErrorLog *log.Logger
    // 内含隐藏或非导出字段
}

Get 请求

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    response, err := http.Get("http://www.baidu.com")
    if err != nil {
    // handle error
    }
    //程序在使用完回复后必须关闭回复的主体。
    defer response.Body.Close()

    body, _ := ioutil.ReadAll(response.Body)
    fmt.Println(string(body))
}

// Golang HTTP GET 添加请求参数
func GetAddQuery(){
    req, err := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular", nil)
    if err != nil {
        log.Print(err)
        os.Exit(1)
    }
    q := req.URL.Query()
    q.Add("api_key", "key_from_environment_or_flag")
    q.Add("another_thing", "foo & bar")
    req.URL.RawQuery = q.Encode()

    fmt.Println(req.URL.String())
    // Output:
    // http://api.themoviedb.org/3/tv/popular?another_thing=foo+%26+bar&api_key=key_from_environment_or_flag
    var resp *http.Response
    resp, err = http.DefaultClient.Do(req)
    if err != nil {
        log.Print(err)
    }
    defer resp.Body.Close()
}

POST 请求

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "bytes"
)

func main() {
    body := "{\"action\":20}"
    res, err := http.Post("http://xxx.com", "application/json;charset=utf-8", bytes.NewBuffer([]byte(body)))
    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.Client和http.NewRequest来模拟请求

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "strings"
)

func main() {
    //利用指定的method,url以及可选的body返回一个新的请求.如果body参数实现了io.Closer接口,Request返回值的Body 字段会被设置为body,并会被Client类型的Do、Post和PostFOrm方法以及Transport.RoundTrip方法关闭。
    body := strings.NewReader("hello world!") //把form数据编下码
    client := &http.Client{}//客户端,被Get,Head以及Post使用
    reqest, err := http.NewRequest("POST", "http://xxx.com/logindo", body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }
    //给一个key设定为响应的value.
    reqest.Header.Set("Content-Type", "application/x-www-form-urlencoded;param=value") //必须设定该参数,POST参数才能正常提交
    
    // HTTP BasicAuth 设置
    request.SetBasicAuth("admin","admin")
    
    resp, err := client.Do(reqest)//发送请求
    defer resp.Body.Close()//一定要关闭resp.Body
    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    fmt.Println(string(content))
}

复杂请求,头参数,cookie 之类

func httpDo() {
    client := &http.Client{}
 
    req, err := http.NewRequest("POST", "http://www.01happy.com/demo/accept.php", strings.NewReader("name=cjb"))
    if err != nil {
        // handle error
    }
 
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("Cookie", "name=anny")
 
    resp, err := client.Do(req)
 
    defer resp.Body.Close()
 
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        // handle error
    }
 
    fmt.Println(string(body))
}

原文地址:https://www.cnblogs.com/shangmo/p/15601457.html