一、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[:])) }