【轉】Golang的HTTP操作大全


Golang提供了官方的http包,對於http操作非常的方便和簡潔。
但是不同於PHP,使用Golang的包來做http操作,還是沒有那么”直接“,需要實例化一下這個,實例化一下那個,有點像Java,因此,為了以后書寫方便,就把基本的請求寫在此。下次用的時候,直接copy就好了。

get 請求

get請求有好幾種方式

直接使用net/http包內的函數請求

import "net/http"
...
resp, err := http.Get("http://wwww.baidu.com")

利用http.client結構體來請求

import "net/http"
...
clt := http.Client{}
resp, err := clt.Get("http://wwww.baidu.com")

 

最本質的請求方式

如果稍微看一下源碼,就會發現以上兩種方式都是用了一下這種最本質的請求方式,

使用http.NewRequest函數

req, err := http.NewRequest("GET", "http://www.baidu.com", nil)

//然后http.client 結構體的 Do 方法
//http.DefaultClient可以換為另外一個http.client
resp, err := http.DefaultClient.Do(req)

Go的get請求面上有好幾種請求方式,實則只有一種:

1、使用http.NewRequest函數獲得request實體。

2、利用http.client結構體的Do方法,將request實體傳入Do方法中。

 

post請求

和get請求類似,post請求也有多種方法,但本質還是使用了http.NewRequest函數和http.clientDo方法。

使用net/http包帶的post方法

import (
"net/http"
"net/url"
)
...
data := url.Values{"start":{"0"}, "offset":{"xxxx"}}
body := strings.NewReader(data.Encode())
resp, err := http.Post("xxxxxxx", "application/x-www-form-urlencoded", body)

或者還可以

import (
"net/http"
"net/url"
)
...
var r http.Request
r.ParseForm()
r.Form.Add("xxx", "xxx")
body := strings.NewReader(r.Form.Encode())
http.Post("xxxx", "application/x-www-form-urlencoded", body)

要是還是覺得復雜,還可以:

import (
"net/http"
"net/url"
)
...
data := url.Values{"start":{"0"}, "offset":{"xxxx"}}
http.PostForm("xxxx", data)

 

使用實例化的http client的post方法

其實本質上直接使用包的函數和實例化的http client是一樣的,包的函數底層也僅僅是實例化了一個DefaultClient,然后調用的DefaultClient的方法。

下面給出使用實例化的http client的post方法:

import (
"net/http"
"net/url"
)
...
data := url.Values{"start":{"0"}, "offset":{"xxxx"}}
body := strings.NewReader(data.Encode())
clt := http.Client{}
resp, err := clt.Post("xxxxxxx", "application/x-www-form-urlencoded", body)

還有

import (
"net/http"
"net/url"
)
...
var r http.Request
r.ParseForm()
r.Form.Add("xxx", "xxx")
body := strings.NewReader(r.Form.Encode())
clt := http.Client{}
clt.Post("xxxx", "application/x-www-form-urlencoded", body)

簡單的,但僅限於form表單

import (
"net/http"
"net/url"
)
...
data := url.Values{"start":{"0"}, "offset":{"xxxx"}}
clt := http.Client{}
clt.PostForm("xxxx", data)

 

使用net/http包的NewRequest函數

其實不管是get方法也好,post方法也好,所有的get、post的的http 請求形式,最終都是會調用net/http包的NewRequest函數,多種多樣的請求形式,也僅僅是封裝的不同而已。

import (
"net/http"
"net/url"
)
...

data := url.Values{"start":{"0"}, "offset":{"xxxx"}}
body := strings.NewReader(data.Encode())

req, err := http.NewRequest("POST", "xxxxx", body)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

clt := http.Client{}
clt.Do(req)

 

添加request header

net/http包沒有封裝直接使用請求帶header的get或者post方法,所以,要想請求中帶header,只能使用NewRequest方法。

import (
"net/http"

)
...

req, err := http.NewRequest("POST", "xxxxx", body)
//此處還可以寫req.Header.Set("User-Agent", "myClient")
req.Header.Add("User-Agent", "myClient")

clt := http.Client{}
clt.Do(req)

有一點需要注意:在添加header操作的時候,req.Header.Addreq.Header.Set都可以,但是在修改操作的時候,只能使用req.Header.Set

這倆方法是有區別的,Golang底層Header的實現是一個map[string][]stringreq.Header.Set方法如果原來Header中沒有值,那么是沒問題的,如果又值,會將原來的值替換掉。而req.Header.Add的話,是在原來值的基礎上,再append一個值,例如,原來header的值是“s”,我后req.Header.Add一個”a”的話,變成了[s a]。但是,獲取header值的方法req.Header.Get確只取第一個,所以,如果原來有值,重新req.Header.Add一個新值的話,req.Header.Get得到的值不變。

 

打印response響應

Golang打印response沒有PHP那么爽,哎,編譯型語言就是麻煩。

import (
    "net/http"
    "net/url"
    "io/ioutil"
)
...
content, err := ioutil.ReadAll(resp.Body)
respBody := string(content)

 

使用cookie

Golang提供了cookie的包net/http/cookiejar

...

url, err := url.Parse("https://www.wukong.com/")
jar, err := cookiejar.New(nil)
jar.SetCookies(url, cookies)//這里的cookies是[]*http.Cookie
wukongClt := http.Client{Transport:nil, Jar:jar}

wukongClt.Get("xxxxx")

Golang的cookie是和http.client聯系在一起的,作為http.client的一個屬性存在。因此,要想在Golang中使用cookie,就必須想辦法構造http.client文中的cookies類型是[] *http.cookie可以自己實例化,有時候也可以從response中直接使用resp.Cookies()直接拿到。

 

使用代理

在Golang中使用http proxy,也必須構造自己的http.client,需要將http.client結構體的一個屬性Transport自己實例化好。

當使用環境變量$http_proxy或$HTTP_PROXY作為代理時

//從環境變量$http_proxy或$HTTP_PROXY中獲取HTTP代理地址
func GetTransportFromEnvironment() (transport *http.Transport) {
    transport = &http.Transport{Proxy : http.ProxyFromEnvironment}
    return
}

參數proxy_addr即代理服務器IP端口號,例如:”http://xxx.xxx.xxx.xxx:6000“,注意,必須加上"http"當使用自己搭建http代理時

func GetTransportFieldURL(proxy_addr *string) (transport *http.Transport) {
    url_i := url.URL{}
    url_proxy, error := url_i.Parse(*proxy_addr)
    if error != nil{
        fmt.Println(error.Error())
    }
    transport = &http.Transport{Proxy : http.ProxyURL(url_proxy)}
    return
}

 

使用的時候,首先調用函數,拿到對應的transport,即使用GetTransportFieldURL或者GetTransportFieldURL函數,然后構建自定義的http.client :

ProxyUrl := "http://xxx.xxx.xxx.xxx:6000"
transport := GetTransportFieldURL(&ProxyUrl)
clt := http.Client{Transport:transport}

clt.Get("http://www.baidu.com")

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM