golang几种post方式
本文内容纲要:
用golang进行http请求类型多了,总结备忘一下。
1.普通的post\get请求
varrhttp.Request
r.ParseForm()
r.Form.Add("uuid",orderUUID)
bodystr:=strings.TrimSpace(r.Form.Encode())
request,err:=http.NewRequest("GET",url,strings.NewReader(bodystr))
iferr!=nil{
//TODO:
}
request.Header.Set("Content-Type","application/x-www-form-urlencoded")
request.Header.Set("Connection","Keep-Alive")
varresp*http.Response
resp,err=http.DefaultClient.Do(request)
iferr!=nil{
//TODO:
}
2.body全部二进制数据流进行post
//body提交二进制数据
funcDoBytesPost(urlstring,data[]byte)([]byte,error){
body:=bytes.NewReader(data)
request,err:=http.NewRequest(POST_METHOD,url,body)
iferr!=nil{
log.Println("http.NewRequest,[err=%s][url=%s]",err,url)
return[]byte(""),err
}
request.Header.Set("Connection","Keep-Alive")
varresp*http.Response
resp,err=http.DefaultClient.Do(request)
iferr!=nil{
log.Println("http.Dofailed,[err=%s][url=%s]",err,url)
return[]byte(""),err
}
deferresp.Body.Close()
b,err:=ioutil.ReadAll(resp.Body)
iferr!=nil{
log.Println("http.Dofailed,[err=%s][url=%s]",err,url)
}
returnb,err
}
3.模拟web表单文件上传进行post
funcnewfileUploadRequest(uristring,paramsmap[string]string,paramName,pathstring)(*http.Request,error){
file,err:=os.Open(path)
iferr!=nil{
returnnil,err
}
deferfile.Close()
body:=&bytes.Buffer{}
writer:=multipart.NewWriter(body)
part,err:=writer.CreateFormFile(paramName,path)
iferr!=nil{
returnnil,err
}
#这里的io.Copy实现,会把file文件都读取到内存里面,然后当做一个buffer传给NewRequest.对于大文件来说会占用很多内存
_,err=io.Copy(part,file)
forkey,val:=rangeparams{
_=writer.WriteField(key,val)
}
err=writer.Close()
iferr!=nil{
returnnil,err
}
request,err:=http.NewRequest("POST",uri,body)
request.Header.Set("Content-Type",writer.FormDataContentType())
returnrequest,err
}
下面这种方式,就是传入文件句柄,然后由requestcopy到socket的缓冲区,而不用全部读取到内存中:
bodyBuf:=bytes.NewBufferString("")
bodyWriter:=multipart.NewWriter(bodyBuf)
//建立文件的http第一部分数据,文件信息
_,err:=bodyWriter.CreateFormFile(paramName,path)
iferr!=nil{
returnnil,err
}
//读取文件,当做http第二部分数据
fh,err:=os.Open(path)
iferr!=nil{
returnnil,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()
iferr!=nil{
returnnil,err
}
req,err:=http.NewRequest("POST",uri,requestReader)
iferr!=nil{
returnnil,err
}
//设置http头
req.Header.Add("Content-Type","multipart/form-data;boundary="+boundary)
req.ContentLength=fi.Size()+int64(bodyBuf.Len())+int64(closeBuf.Len())
gopackage的实现源码:
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
本文内容总结:
原文链接:https://www.cnblogs.com/zhangqingping/p/4598337.html