用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][url=%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 的实现源码:

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

golang几种post方式的更多相关文章

  1. 保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java、Golang两种客户端教学Case)

    保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java.Golang两种客户端教学Case)   目录 什么是AMQP 和 JMS? 常见的MQ产品 安装RabbitM ...

  2. Web APi之认证(Authentication)两种实现方式【二】(十三)

    前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再叙述废话. 序言 对于所谓的认证说到底 ...

  3. CSS垂直居中的11种实现方式

    今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...

  4. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  5. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

  6. Android开发之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...

  7. 通过三个DEMO学会SignalR的三种实现方式

    一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...

  8. Hive metastore三种配置方式

    http://blog.csdn.net/reesun/article/details/8556078 Hive的meta数据支持以下三种存储方式,其中两种属于本地存储,一种为远端存储.远端存储比较适 ...

  9. Hive的三种安装方式(内嵌模式,本地模式远程模式)

    一.安装模式介绍:     Hive官网上介绍了Hive的3种安装方式,分别对应不同的应用场景.     1.内嵌模式(元数据保村在内嵌的derby种,允许一个会话链接,尝试多个会话链接时会报错)   ...

随机推荐

  1. python学习笔记(10)--爬虫下载煎蛋图片

    说明: 1. 有很多细节需要注意! 2. str是保留字,不要作为变量名 3. 保存为txt报错,encoding=utf-8 4. 403错误,添加headers的方法 5. 正则match只能从开 ...

  2. cocos2dx迷你地图

    用CCRenderTexture就可以了,不知是否有更好的方法. if (!miniMap) { miniMap=CCSprite::create(); miniMap->setZOrder() ...

  3. 大数据(11) - kafka的安装与使用

    一.Kafka概述 1.Kafka是什么 在流式计算中,Kafka一般用来缓存数据,Storm通过消费Kafka的数据进行计算. 1)Apache Kafka是一个开源消息系统,由Scala写成.是由 ...

  4. 二分图匹配 + 最小点覆盖 - Vertex Cover

    Vertex Cover Problem's Link Mean: 给你一个无向图,让你给图中的结点染色,使得:每条边的两个顶点至少有一个顶点被染色.求最少的染色顶点数. analyse: 裸的最小点 ...

  5. JS侦测设备旋转方向

    window.onload = window.onresize = function initialLoad(){updateOrientation();} function updateOrient ...

  6. imx lcd HV和DE模式转换

    有些时候拿到的lcd手册中关于芯片的时序使用的DE模式的,而imx6内核中使用的参数设置趋势HV模式,应此就需要将DE模式的参数转化为HV模式. 参考链接: https://community.nxp ...

  7. 第二百八十一节,MySQL数据库-SQL注入和pymysql模块防止SQL注入

    MySQL数据库-SQL注入和pymysql模块防止SQL注入 SQL注入就是通过SQL语句绕开程序判断,获取到数据库的内容 下面以一个简单的程序登录SQL注入举例: 正常登录 1.数据库有一张会员表 ...

  8. MyBatis 最强大的特性之一就是它的动态语句功能

    MyBatis 最强大的特性之一就是它的动态语句功能.如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略 ...

  9. 【noip模拟题】挖掘机(模拟题+精度)

    这题直接模拟. 可是我挂在了最后两个点上QAQ.唯一注意的是注意精度啊...用来double后边转成整数就忘记用longlong...sad #include <cstdio> #incl ...

  10. 【OpenWRT】网络配置

    cd /etc/config vim network vim wireless cd /etc/init.d/network