欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang中http包的具體使用

 更新時(shí)間:2024年05月14日 09:16:33   作者:兩片空白  
Go語(yǔ)言內(nèi)置的net/http包十分優(yōu)秀,提供了http客戶端和服務(wù)器的實(shí)現(xiàn),本文主要介紹了Golang中http包的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下

Go語(yǔ)言內(nèi)置的net/http包十分優(yōu)秀,提供了http客戶端和服務(wù)器的實(shí)現(xiàn)。

超文本傳輸協(xié)議(HTTP,HyperText Transfer Protocol)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)傳輸協(xié)議,所有的www文件都必須遵循這個(gè)標(biāo)準(zhǔn)。設(shè)計(jì)HTTP最初的目的是為了提供一種發(fā)布和接收HTML頁(yè)面的方法。

一. HTTP客戶端

基本的HTTP/HTTPS請(qǐng)求Get,Head,Post和PostForm函數(shù)發(fā)出HTTP/HTTPS請(qǐng)求。

	resp, err := http.Get("http://example.com")
	//...
	resp, err = http.Post("http://example.com", "image/jpeg", &buf)
	//...
	resp, err = http.PostForm("http://example.com", url.Values{"key": {"value"}, "id": {"123"}})

程序在使用完response后必須關(guān)閉回復(fù)的主體。

package main

import (
	"io/ioutil"
	"log"
	"net/http"
)

func main() {
	resp, err := http.Get("http://example.com")
	if err != nil {
		log.Println("http get fail")
		return
	}
	//關(guān)閉回復(fù)主體
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
    //...
}

1.1 Get請(qǐng)求

函數(shù)簽名:

func Get(url string) (resp *Response, err error)

Get向指定的URL發(fā)出Get請(qǐng)求,如果回應(yīng)的狀態(tài)碼如下,Get會(huì)調(diào)用c.CheckRedirect后執(zhí)行重定向。

  • 301(Moved Permanently)
  • 302(Found)
  • 303(See Other)
  • 307(Temporary Redirect)

如果c.CheckRedirect執(zhí)行失敗或存在HTTP協(xié)議錯(cuò)誤時(shí),本方法返回錯(cuò)誤。如果回應(yīng)的狀態(tài)碼不是2xx,本方法并不會(huì)返回錯(cuò)誤。如果返回值err為nil,resp.Body總是非nil的,調(diào)用者應(yīng)該在讀取完resp.Body后關(guān)閉它。

Get是對(duì)DefaultClient的Get方法的包裝。

1.2 post和get示例服務(wù)端代碼

package main

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

func getHandleFunc(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	data := r.URL.Query() //獲得get方法的參數(shù)
	fmt.Println(data.Get("name"))
	fmt.Println(data.Get("age"))

	answer := `{"status":"ok"}`
	w.Write([]byte(answer))
}

func postHandleFunc(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	//請(qǐng)求數(shù)據(jù)類(lèi)型是application/json
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println("read request body fail ", err)
		return
	}
	fmt.Println(string(b))

	answer := `{"statue":"ok"}`
	w.Write([]byte(answer))
}

func handleFunc(w http.ResponseWriter, r *http.Request) {
	fmt.Println("get a link....")
	switch r.Method {
	case http.MethodGet:
		http.HandleFunc("/get", getHandleFunc)
	case http.MethodPost:
		http.HandleFunc("/post", postHandleFunc)
	}
}

func main() {
	http.HandleFunc("/", handleFunc)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		fmt.Println("http server fail ", err)
		return
	}
}

1.3 get方法示例

不帶參數(shù)客戶端

package main

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

func main() {
	resp, err := http.Get("https://www.baidu.com")
	if err != nil {
		log.Println("http get fail ", err)
		return
	}
	//關(guān)閉回復(fù)主體
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("read resp body fail ", err)
		return
	}

	fmt.Print(string(body))
}

帶參數(shù)客戶端

關(guān)于Get請(qǐng)求帶參數(shù)需要使用Go語(yǔ)言內(nèi)置的net/url標(biāo)準(zhǔn)庫(kù)來(lái)處理。

package main

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

func main() {
	apiUrl := "http://127.0.0.1:9090/get"
	//URL參數(shù)
	data := url.Values{}
	data.Set("name", "張三")
	data.Set("age", "20")

	//URL參數(shù)需要編碼,因?yàn)橛械奶厥庾址毁x予了特殊含義
	u, err := url.ParseRequestURI(apiUrl)
	if err != nil {
		fmt.Println("url parse fail ", err)
	}
	u.RawQuery = data.Encode() //url encode
	fmt.Println(u.String())

	resp, err := http.Get(u.String())
	if err != nil {
		fmt.Printf("url %v get fail %v", u.String(), err)
		return
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("read body fail ", err)
		return
	}
	fmt.Println(string(b))
}

1.4 post請(qǐng)求

函數(shù)簽名:

func Post(url string, bodyType string, body io.Reader) (resp *Response, err error)

Post向指定的URL發(fā)送一個(gè)POST請(qǐng)求。bodyType為POST的數(shù)據(jù)類(lèi)型,Body為POST數(shù)據(jù),作為請(qǐng)求的主體。如果參數(shù)body實(shí)現(xiàn)了io.Closer接口,它會(huì)在發(fā)送請(qǐng)求后被關(guān)閉。調(diào)用者有責(zé)任在讀取完返回值resp的主體后關(guān)閉它。

Post是對(duì)包變量DefaultClient的Post方法的包裝。

1.5 post示例

package main

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

func main() {
	apiUrl := "http://127.0.0.1:9090/post"

	//表單數(shù)據(jù)
	contenttype := "application/json"
	data := `{"name":"張三", "age":18}`
	resp, err := http.Post(apiUrl, contenttype, strings.NewReader(data))
	if err != nil {
		fmt.Printf("url : %v post fail err : %v\n", apiUrl, err)
		return
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("read body err ", err)
		return
	}
	fmt.Println(string(b))
}

1.6 自定義Client

要管理HTTP客戶端頭域,重定向和其它策略,創(chuàng)建一個(gè)client:

type Client struct {
    // Transport指定執(zhí)行獨(dú)立、單次HTTP請(qǐng)求的機(jī)制。
    // 如果Transport為nil,則使用DefaultTransport。
    Transport RoundTripper
    // CheckRedirect指定處理重定向的策略。
    // 如果CheckRedirect不為nil,客戶端會(huì)在執(zhí)行重定向之前調(diào)用本函數(shù)字段。
    // 參數(shù)req和via是將要執(zhí)行的請(qǐng)求和已經(jīng)執(zhí)行的請(qǐng)求(切片,越新的請(qǐng)求越靠后)。
    // 如果CheckRedirect返回一個(gè)錯(cuò)誤,本類(lèi)型的Get方法不會(huì)發(fā)送請(qǐng)求req,
    // 而是返回之前得到的最后一個(gè)回復(fù)和該錯(cuò)誤。(包裝進(jìn)url.Error類(lèi)型里)
    //
    // 如果CheckRedirect為nil,會(huì)采用默認(rèn)策略:連續(xù)10此請(qǐng)求后停止。
    CheckRedirect func(req *Request, via []*Request) error
    // Jar指定cookie管理器。
    // 如果Jar為nil,請(qǐng)求中不會(huì)發(fā)送cookie,回復(fù)中的cookie會(huì)被忽略。
    Jar CookieJar
    // Timeout指定本類(lèi)型的值執(zhí)行請(qǐng)求的時(shí)間限制。
    // 該超時(shí)限制包括連接時(shí)間、重定向和讀取回復(fù)主體的時(shí)間。
    // 計(jì)時(shí)器會(huì)在Head、Get、Post或Do方法返回后繼續(xù)運(yùn)作并在超時(shí)后中斷回復(fù)主體的讀取。
    //
    // Timeout為零值表示不設(shè)置超時(shí)。
    //
    // Client實(shí)例的Transport字段必須支持CancelRequest方法,
    // 否則Client會(huì)在試圖用Head、Get、Post或Do方法執(zhí)行請(qǐng)求時(shí)返回錯(cuò)誤。
    // 本類(lèi)型的Transport字段默認(rèn)值(DefaultTransport)支持CancelRequest方法。
    Timeout time.Duration
}

Client類(lèi)型代表HTTP客戶端。它的零值(DefaultClient)是一個(gè)可用的使用DefaultTransport的客戶端。

Client的Transport字段一般會(huì)含有內(nèi)部狀態(tài)(緩存TCP連接),因此Client類(lèi)型值應(yīng)盡量被重用而不是每次需要都創(chuàng)建新的。Client類(lèi)型值可以安全的被多個(gè)go程同時(shí)使用。

Client類(lèi)型的層次比RoundTripper接口(如Transport)高,還會(huì)管理HTTP的cookie和重定向等細(xì)節(jié)。

//設(shè)置重定向
client := &http.Client{
    CheckRedirect : redirectPolicyFunc,
}

resp, err := client.Get("http://example.com")
//...

//加請(qǐng)求頭部
req, err := http.NewRequest("Get", "http://example.com", nil)
//...

req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
//...

1.7 自定義Transport

go語(yǔ)言中的http.transport是一個(gè)高性能的http客戶端庫(kù),它提供了連接池、重試、超時(shí)控制等功能,可以方便地進(jìn)行 http 請(qǐng)求。

要管理代理,TLS配置,keep-alive,壓縮和其它設(shè)置,可以創(chuàng)建一個(gè)Transport,對(duì)應(yīng)Client的Transport字段。

type Transport struct {
    // Proxy指定一個(gè)對(duì)給定請(qǐng)求返回代理的函數(shù)。
    // 如果該函數(shù)返回了非nil的錯(cuò)誤值,請(qǐng)求的執(zhí)行就會(huì)中斷并返回該錯(cuò)誤。
    // 如果Proxy為nil或返回nil的*URL置,將不使用代理。
    Proxy func(*Request) (*url.URL, error)
    // Dial指定創(chuàng)建TCP連接的撥號(hào)函數(shù)。如果Dial為nil,會(huì)使用net.Dial。
    Dial func(network, addr string) (net.Conn, error)
    // TLSClientConfig指定用于tls.Client的TLS配置信息。
    // 如果該字段為nil,會(huì)使用默認(rèn)的配置信息。
    TLSClientConfig *tls.Config
    // TLSHandshakeTimeout指定等待TLS握手完成的最長(zhǎng)時(shí)間。零值表示不設(shè)置超時(shí)。
    TLSHandshakeTimeout time.Duration
    // 如果DisableKeepAlives為真,會(huì)禁止不同HTTP請(qǐng)求之間TCP連接的重用。
    DisableKeepAlives bool
    // 如果DisableCompression為真,會(huì)禁止Transport在請(qǐng)求中沒(méi)有Accept-Encoding頭時(shí),
    // 主動(dòng)添加"Accept-Encoding: gzip"頭,以獲取壓縮數(shù)據(jù)。
    // 如果Transport自己請(qǐng)求gzip并得到了壓縮后的回復(fù),它會(huì)主動(dòng)解壓縮回復(fù)的主體。
    // 但如果用戶顯式的請(qǐng)求gzip壓縮數(shù)據(jù),Transport是不會(huì)主動(dòng)解壓縮的。
    DisableCompression bool
    // 如果MaxIdleConnsPerHost!=0,會(huì)控制每個(gè)主機(jī)下的最大閑置連接。
    // 如果MaxIdleConnsPerHost==0,會(huì)使用DefaultMaxIdleConnsPerHost。
    MaxIdleConnsPerHost int
    // ResponseHeaderTimeout指定在發(fā)送完請(qǐng)求(包括其可能的主體)之后,
    // 等待接收服務(wù)端的回復(fù)的頭域的最大時(shí)間。零值表示不設(shè)置超時(shí)。
    // 該時(shí)間不包括獲取回復(fù)主體的時(shí)間。
    ResponseHeaderTimeout time.Duration
    // 內(nèi)含隱藏或非導(dǎo)出字段
}
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{
			RootCAs: pool,
		},
		DisableCompression: true,
	}

	client := &http.Client{
		Transport: tr,
	}

	resp, err := client.Get("http://example.com")
	//...

二. 服務(wù)端

2.1 默認(rèn)server

ListenAndServer使用指定的監(jiān)聽(tīng)地址和處理器啟動(dòng)一個(gè)HTTP服務(wù)端。處理器參數(shù)通常是nil,這表示采用包變量DefaultServeMux作為處理器。

Handle和HandleFunc函數(shù)可以向DefaultServeMux添加處理器。

	http.Handle("/foo", fooHandler)
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "hello %q", html.EscapeString(r.URL.Path))
	})

	log.Fatal(http.ListenAndServe(":8080", nil))

2.2 示例

package main

import (
	"fmt"
	"net/http"
)

func sayHello(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	fmt.Fprintln(w, "hello 張三")
}

func main() {
	http.HandleFunc("/", sayHello)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		fmt.Println("http server fail, err ", err)
		return
	}
}

2.3 自定義Server

type Server struct {
    Addr           string        // 監(jiān)聽(tīng)的TCP地址,如果為空字符串會(huì)使用":http"
    Handler        Handler       // 調(diào)用的處理器,如為nil會(huì)調(diào)用http.DefaultServeMux
    ReadTimeout    time.Duration // 請(qǐng)求的讀取操作在超時(shí)前的最大持續(xù)時(shí)間
    WriteTimeout   time.Duration // 回復(fù)的寫(xiě)入操作在超時(shí)前的最大持續(xù)時(shí)間
    MaxHeaderBytes int           // 請(qǐng)求的頭域最大長(zhǎng)度,如為0則用DefaultMaxHeaderBytes
    TLSConfig      *tls.Config   // 可選的TLS配置,用于ListenAndServeTLS方法
    // TLSNextProto(可選地)指定一個(gè)函數(shù)來(lái)在一個(gè)NPN型協(xié)議升級(jí)出現(xiàn)時(shí)接管TLS連接的所有權(quán)。
    // 映射的鍵為商談的協(xié)議名;映射的值為函數(shù),該函數(shù)的Handler參數(shù)應(yīng)處理HTTP請(qǐng)求,
    // 并且初始化Handler.ServeHTTP的*Request參數(shù)的TLS和RemoteAddr字段(如果未設(shè)置)。
    // 連接在函數(shù)返回時(shí)會(huì)自動(dòng)關(guān)閉。
    TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
    // ConnState字段指定一個(gè)可選的回調(diào)函數(shù),該函數(shù)會(huì)在一個(gè)與客戶端的連接改變狀態(tài)時(shí)被調(diào)用。
    // 參見(jiàn)ConnState類(lèi)型和相關(guān)常數(shù)獲取細(xì)節(jié)。
    ConnState func(net.Conn, ConnState)
    // ErrorLog指定一個(gè)可選的日志記錄器,用于記錄接收連接時(shí)的錯(cuò)誤和處理器不正常的行為。
    // 如果本字段為nil,日志會(huì)通過(guò)log包的標(biāo)準(zhǔn)日志記錄器寫(xiě)入os.Stderr。
    ErrorLog *log.Logger
    // 內(nèi)含隱藏或非導(dǎo)出字段
}

要管理服務(wù)端的行為,可以創(chuàng)建一個(gè)自定義的Server:

	s := &http.Server{
		Addr:           ":8080",
		Handler:        myHander,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

到此這篇關(guān)于Golang中http包的具體使用的文章就介紹到這了,更多相關(guān)Golang http包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • win10下安裝Go和Goland的詳細(xì)教程

    win10下安裝Go和Goland的詳細(xì)教程

    這篇文章主要介紹了win10下安裝Go和Goland的詳細(xì)教程,本文給大家提到了go和golang之間的區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Golang中的path/filepath包用法

    Golang中的path/filepath包用法

    這篇文章主要介紹了Golang中的path/filepath包用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • 淺析Go語(yǔ)言中數(shù)組的使用

    淺析Go語(yǔ)言中數(shù)組的使用

    數(shù)組用于在單個(gè)變量中存儲(chǔ)相同類(lèi)型的多個(gè)值,而不是為每個(gè)值聲明單獨(dú)的變量,這篇文章主要為大家介紹了Go語(yǔ)言中數(shù)組的簡(jiǎn)單使用,需要?的可以參考下
    2023-08-08
  • Go語(yǔ)言O(shè)RM框架構(gòu)造查詢條件示例詳解

    Go語(yǔ)言O(shè)RM框架構(gòu)造查詢條件示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言O(shè)RM框架構(gòu)造查詢條件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 淺析Go語(yǔ)言中的逃逸分析

    淺析Go語(yǔ)言中的逃逸分析

    在Go語(yǔ)言中,內(nèi)存分配和逃逸分析是至關(guān)重要的概念,對(duì)于理解代碼的性能和內(nèi)存使用情況至關(guān)重要,本文將深入探討Go語(yǔ)言中的內(nèi)存分配原理以及逃逸分析的作用,希望對(duì)大家有所幫助
    2024-04-04
  • Go中Vendo機(jī)制的使用

    Go中Vendo機(jī)制的使用

    自Go1.6起,Go語(yǔ)言正式啟用vendor機(jī)制,允許將項(xiàng)目依賴(lài)放入項(xiàng)目?jī)?nèi)的vendor目錄,類(lèi)似私有GOPATH,本文就來(lái)介紹一下Vendo機(jī)制的使用,感興趣的可以了解一下
    2024-10-10
  • Golang使用ini庫(kù)讀取配置詳情

    Golang使用ini庫(kù)讀取配置詳情

    這篇文章主要介紹了Golang使用ini庫(kù)讀取配置詳情,go-ini是一個(gè)非常方便、高效的go配置文件操作庫(kù)。使用它在項(xiàng)目中讀取和修改配置文件,下文相關(guān)資料需要的小伙伴可可以參考一下
    2022-04-04
  • Golang連接池的幾種實(shí)現(xiàn)案例小結(jié)

    Golang連接池的幾種實(shí)現(xiàn)案例小結(jié)

    這篇文章主要介紹了Golang連接池的幾種實(shí)現(xiàn)案例小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • golang gorm 操作mysql及gorm基本用法

    golang gorm 操作mysql及gorm基本用法

    golang 官方的那個(gè)操作mysql的有點(diǎn)麻煩所以就使用了gorm,下面就gorm的使用做下簡(jiǎn)單介紹,感興趣的朋友跟隨小編一起看看吧
    2018-11-11
  • Go操作etcd的實(shí)現(xiàn)示例

    Go操作etcd的實(shí)現(xiàn)示例

    etcd是近幾年比較火熱的一個(gè)開(kāi)源的、分布式的鍵值對(duì)數(shù)據(jù)存儲(chǔ)系統(tǒng),提供共享配置、服務(wù)的注冊(cè)和發(fā)現(xiàn),本文主要介紹etcd的安裝和使用,感興趣的可以了解一下
    2021-09-09

最新評(píng)論