您的位置:首页 > 编程语言 > Go语言

golang几种post方式

2015-06-24 18:04 483 查看
用golang进行http请求类型多了,总结备忘一下。

1.普通的post\get请求

   var r http.Request
 r.ParseForm()
r.Form.Add("uuid", orderUUID)
bodystr := strings.TrimSpace(r.Form.Encode())
request, err := http.NewRequest("GET", url, strings.NewReader(bodystr))
if err != nil {
  //TODO:
}
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.Header.Set("Connection", "Keep-Alive")

var resp *http.Response
resp, err = http.DefaultClient.Do(request)
if err != nil {
    //TODO:
}


2. body全部二进制数据流进行post

//body提交二进制数据
func DoBytesPost(url string, data []byte) ([]byte, error) {

 body := bytes.NewReader(data)
request, err := http.NewRequest(POST_METHOD, url, body)
if err != nil {
log.Println("http.NewRequest,[err=%s]", err, url)
return []byte(""), err
}
request.Header.Set("Connection", "Keep-Alive")
var resp *http.Response
resp, err = http.DefaultClient.Do(request)
if err != nil {
log.Println("http.Do failed,[err=%s][url=%s]", err, url)
return []byte(""), err
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("http.Do failed,[err=%s][url=%s]", err, url)
}
return b, err
}


3. 模拟web表单文件上传进行post

func newfileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()

 body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile(paramName, path)
if err != nil {
return nil, err
}
# 这里的io.Copy实现,会把file文件都读取到内存里面,然后当做一个buffer传给NewRequest. 对于大文件来说会占用很多内存
_, err = io.Copy(part, file)

for key, val := range params {
_ = writer.WriteField(key, val)
}
err = writer.Close()
if err != nil {
return nil, err
}
request, err := http.NewRequest("POST", uri, body)
request.Header.Set("Content-Type", writer.FormDataContentType())
return request, err
}


下面这种方式,就是传入文件句柄,然后由request copy到socket的缓冲区,而不用全部读取到内存中:

bodyBuf := bytes.NewBufferString("")
bodyWriter := multipart.NewWriter(bodyBuf)

//建立文件的http第一部分数据,文件信息
_, err := bodyWriter.CreateFormFile(paramName, path)
if err != nil {
return nil, err
}

//读取文件,当做http第二部分数据
fh, err := os.Open(path)
if err != nil {
return nil, err
}
//mulitipart/form-data时,需要获取自己关闭的boundary
 boundary := bodyWriter.Boundary()
closeBuf := bytes.NewBufferString(fmt.Sprintf("\r\n--%s--\r\n", boundary))

//建立写入socket的reader对象
requestReader := io.MultiReader(bodyBuf, fh, closeBuf)

fi, err := fh.Stat()
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", uri, requestReader)
if err != nil {
return nil, err
}
//设置http头
req.Header.Add("Content-Type", "multipart/form-data; boundary="+boundary)
req.ContentLength = fi.Size() + int64(bodyBuf.Len()) + int64(closeBuf.Len())


go package 的实现源码:

[url=http://golang.org/src/io/io.go?s=12247:12307#L340]http://golang.org/src/io/io.go?s=12247:12307#L340


https://golang.org/src/io/multi.go?h=MultiReader#L31

https://golang.org/src/net/http/transfer.go?h=WriteBody#L199

https://golang.org/src/net/http/request.go?h=write#L366

参考连接:

https://groups.google.com/forum/#!topic/golang-nuts/Zjg5l4nKcQ0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: