Go发起Http请求及获取相关参数

golang要请求远程网页,可以使用net/http包中的client提供的方法实现。查看了官方网站有一些示例,没有太全面的例子,于是自己整理了一下。

get请求

get请求可以直接http.Get方法,非常简单。

func httpGet() {
	resp, err := http.Get("http://www.01happy.com/demo/accept.php?id=1")
	if err != nil {
		// handle error
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
	}

	fmt.Println(string(body))
}

post请求

一种是使用http.Post方式

func httpPost() {
	resp, err := http.Post("http://www.01happy.com/demo/accept.php",
		"application/x-www-form-urlencoded",
		strings.NewReader("name=cjb"))
	if err != nil {
		fmt.Println(err)
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
	}

	fmt.Println(string(body))
}

Tips:使用这个方法的话,第二个参数要设置成”application/x-www-form-urlencoded”,否则post参数无法传递。

一种是使用http.PostForm方法

func httpPostForm() {
	resp, err := http.PostForm("http://www.01happy.com/demo/accept.php",
		url.Values{"key": {"Value"}, "id": {"123"}})

	if err != nil {
		// handle error
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
	}

	fmt.Println(string(body))

}

复杂的请求

有时需要在请求的时候设置头参数、cookie之类的数据,就可以使用http.Do方法。

func httpDo() {
	client := &http.Client{}

	req, err := http.NewRequest("POST", "http://www.01happy.com/demo/accept.php", strings.NewReader("name=cjb"))
	if err != nil {
		// handle error
	}

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Cookie", "name=anny")

	resp, err := client.Do(req)

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
	}

	fmt.Println(string(body))
}

同上面的post请求,必须要设定Content-Type为application/x-www-form-urlencoded,post参数才可正常传递。

如果要发起head请求可以直接使用http client的head方法,比较简单,这里就不再说明。

完整代码示例文件下载:golang_http_client发起get和post代码示例

 

转载请注明:快乐编程 » golang使用http client发起get和post请求示例

 

在成熟的语言java、python、php要获取这些参数应该来讲都非常简单,过较新的语言golang用获取这些个参数还是费了不少劲,特此记录一下。

golang版本:1.3.1

在贴代码之前如果能先理解一下golang http.request的三个属性Form、PostForm、MultipartForm应该能较好的理解代码,下面摘录一下。

 

Form、PostForm、MultipartForm说明

 

简要说明一下

Form:存储了post、put和get参数,在使用之前需要调用ParseForm方法。
PostForm:存储了post、put参数,在使用之前需要调用ParseForm方法。
MultipartForm:存储了包含了文件上传的表单的post参数,在使用前需要调用ParseMultipartForm方法。

获取GET参数

网上比较常见的一个版本是:

r.ParseForm()
if len(r.Form["id"]) > 0 {
	fmt.Fprintln(w, r.Form["id"][0])
}

其中r表示*http.Request类型,w表示http.ResponseWriter类型。

r.Form是url.Values字典类型,r.Form["id"]取到的是一个数组类型。因为http.request在解析参数的时候会将同名的参数都放进同一个数组里,所以这里要用[0]获取到第一个。

这种取法在通常情况下都没有问题,但是如果是如下请求则无法取到需要的值:

因为r.Form包含了get和post参数,并且以post参数为先,上例post参数和get参数都有id,所以应当会取到post参数2。虽然这种情况并不多见,但是从严谨的角度来看程序上还是应当处理这种情况。立马补上改进代码:

queryForm, err := url.ParseQuery(r.URL.RawQuery)
if err == nil && len(queryForm["id"]) > 0 {
	fmt.Fprintln(w, queryForm["id"][0])
}

代码比较简单,就是分析url问号后的参数。事实上这个也是标准库ParseForm中关于get参数解析代码。

获取POST参数

这里要分两种情况:

  1. 普通的post表单请求,Content-Type=application/x-www-form-urlencoded
  2. 有文件上传的表单,Content-Type=multipart/form-data

第一种情况比较简单,直接用PostFormValue就可以取到了。

fmt.Fprintln(w, r.PostFormValue("id"))

第二种情况复杂一些,如下表单:

因为需要上传文件,所以表单enctype要设置成multipart/form-data。此时无法通过PostFormValue来获取id的值,因为golang库里还未实现这个方法:

 

Go发起Http请求及获取相关参数_第1张图片

golang中不能用PostForm获取post参数

 

幸好golang中可以提供了另外一个属性MultipartForm来处理这种情况。

r.ParseMultipartForm(32 << 20)
if r.MultipartForm != nil {
	values := r.MultipartForm.Value["id"]
	if len(values) > 0 {
		fmt.Fprintln(w, values[0])
	}
}

感谢:在测试post的时候,一开始都是以第二种情况来测试的,所以造成了一个误区以为PostFormValue无法取到值。这里感谢@九头蛇龙 的纠正。

获取COOKIE参数

cookie, err := r.Cookie("id")
if err == nil {
	fmt.Fprintln(w, "Domain:", cookie.Domain)
	fmt.Fprintln(w, "Expires:", cookie.Expires)
	fmt.Fprintln(w, "Name:", cookie.Name)
	fmt.Fprintln(w, "Value:", cookie.Value)
}

r.Cookie返回*http.Cookie类型,可以获取到domain、过期时间、值等数据。

小结

在折腾的过程中看了下net/http包中的源码,感觉在web开发中还是有很多不完善的地方。作为使用者来讲,最希望就是直接通过一个方法取到相应的值就可以了,期待官方团队尽早完善。

 

转载请注明:快乐编程 » golang web开发获取get、post、cookie参数

 

你可能感兴趣的:(Golang)