用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