一、post請求的Content-Type為鍵值對
1、PostForm方式
package main
import (
"net/http"
"net/url"
"fmt"
"io/ioutil"
"bytes"
"strings"
"mime/multipart"
"os"
"io"
"time"
)
func main() {
postForm1()
}
//以PostForm的方式傳送body為鍵值對的post請求
func postForm1() {
//這是一個Post 引數會被返回的地址 `這裡寫程式碼片`
uri:="http://127.0.0.1:8888/test"
data := urlValues()
resopne,err:= http.PostForm(uri,data)
if err !=nil {
fmt.Println("err=",err)
}
//http返回的response的body必須close,否則就會有記憶體洩露
defer func() {
resopne.Body.Close()
fmt.Println("finish")
}()
body,err:=ioutil.ReadAll(resopne.Body)
if err!=nil {
fmt.Println(" post err=",err)
}
fmt.Println(string(body))
}
//獲取鍵值對的body
func urlValues() url.Values{
//方式1
data1 := url.Values{"name":{"TiMi"},"id":{"123"}}
fmt.Println(data1)
//方式2
data2 := url.Values{}
data2.Set("name", "TiMi")
data2.Set("id", "123")
fmt.Println(data2)
//方式3
data3 := make(url.Values)
data3["name"] = []string{"TiMi"}
data3["id"] = []string{"123"}
fmt.Println(data3)
/*
map[id:[123] name:[TiMi]]
map[id:[123] name:[TiMi]]
map[id:[123] name:[TiMi]]
*/
return data1
}
2、Do方式
package main
import (
"net/http"
"net/url"
"fmt"
"io/ioutil"
"bytes"
"strings"
"mime/multipart"
"os"
"io"
"time"
)
func main() {
postForm2()
}
//以Do的方式傳送body為鍵值對的post請求
func postForm2() {
uri := "http://127.0.0.1:8888"
resource := "/test"
data := urlValues()
u, _ := url.ParseRequestURI(uri)
u.Path = resource
urlStr := u.String()
client := &http.Client{}
r, _ := http.NewRequest("POST", urlStr, strings.NewReader(data.Encode()))
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := client.Do(r)
if err != nil {
fmt.Println(err.Error())
return
}
//http返回的response的body必須close,否則就會有記憶體洩露
defer func() {
res.Body.Close()
fmt.Println("finish")
}()
//讀取body
body,err:=ioutil.ReadAll(res.Body)
if err!=nil {
fmt.Println(" post err=",err)
}
fmt.Println(string(body))
}
func urlValues() url.Values{
//方式1
data1 := url.Values{"name":{"TiMi"},"id":{"123"}}
fmt.Println(data1)
//方式2
data2 := url.Values{}
data2.Set("name", "TiMi")
data2.Set("id", "123")
fmt.Println(data2)
//方式3
data3 := make(url.Values)
data3["name"] = []string{"TiMi"}
data3["id"] = []string{"123"}
fmt.Println(data3)
/*
map[id:[123] name:[TiMi]]
map[id:[123] name:[TiMi]]
map[id:[123] name:[TiMi]]
*/
return data1
}
二、post請求傳送檔案
1、以二進位制形式上傳
package main
import (
"net/http"
"net/url"
"fmt"
"io/ioutil"
"bytes"
"strings"
"mime/multipart"
"os"
"io"
"time"
)
func main() {
postFile1()
}
//以二進位制格式上傳檔案
func postFile1(){
//這是一個Post 引數會被返回的地址
uri:="http://127.0.0.1:8888/test"
byte,err:=ioutil.ReadFile("redis_file.zip")
res,err :=http.Post(uri,"multipart/form-data",bytes.NewReader(byte))
if err !=nil {
fmt.Println("err=",err)
}
//http返回的response的body必須close,否則就會有記憶體洩露
defer func() {
res.Body.Close()
fmt.Println("finish")
}()
//讀取body
body,err:=ioutil.ReadAll(res.Body)
if err!=nil {
fmt.Println(" post err=",err)
}
fmt.Println(string(body))
}
2、以鍵值對形式上傳
package main
import (
"net/http"
"net/url"
"fmt"
"io/ioutil"
"bytes"
"strings"
"mime/multipart"
"os"
"io"
"time"
)
func main() {
postFile2()
}
//以鍵值對形式上傳檔案
func postFile2() {
uri := "http://127.0.0.1:8888/test"
paramName := "file"
filePath := "redis_file.zip"
//開啟要上傳的檔案
file, err := os.Open(filePath)
if err != nil {
fmt.Println(" post err=",err)
}
defer file.Close()
body := &bytes.Buffer{}
//建立一個multipart型別的寫檔案
writer := multipart.NewWriter(body)
//使用給出的屬性名paramName和檔名filePath建立一個新的form-data頭
part, err := writer.CreateFormFile(paramName, filePath)
if err != nil {
fmt.Println(" post err=",err)
}
//將源複製到目標,將file寫入到part 是按預設的緩衝區32k迴圈操作的,不會將內容一次性全寫入記憶體中,這樣就能解決大檔案的問題
_, err = io.Copy(part, file)
err = writer.Close()
if err != nil {
fmt.Println(" post err=",err)
}
request, err := http.NewRequest("POST", uri, body)
request.Header.Add("S-COOKIE2", "a=2l=310260000000000&m=460&n=00")
//writer.FormDataContentType() : 返回w對應的HTTP multipart請求的Content-Type的值,多以multipart/form-data起始
request.Header.Set("Content-Type", writer.FormDataContentType())
//設定host,只能用request.Host = “”,不能用request.Header.Add(),也不能用request.Header.Set()來新增host
request.Host = "api.shouji.com"
t := http.DefaultTransport.(*http.Transport).Clone()
t.MaxIdleConns = 100
t.MaxConnsPerHost = 100
t.MaxIdleConnsPerHost = 100
clt := http.Client{
Timeout: 10 * time.Second,
Transport: t,
}
defer clt.CloseIdleConnections()
res, err := clt.Do(request)
//http返回的response的body必須close,否則就會有記憶體洩露
defer func() {
res.Body.Close()
fmt.Println("finish")
}()
if err != nil {
fmt.Println("err is ", err)
}
body1, err1 := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("ioutil.ReadAll err is ", err1)
return
}
fmt.Println(string(body1[:]))
}