以前阅读过Gin源码、并仿照Gin自己写了一个简单版的框架。
最近在使用的时候,发现前端调用传递参数方式各异,各种稀奇古怪的方式都会用到。这篇文章主要盘一下如何获取到参数,方便今后使用。
代码位置:https://github.com/shidawuhen/asap/tree/master/controller/paramtype
1.类型
HTTP请求方法有很多
我们常用的是GET和POST,本次主要讲GET和POST,差不多可以覆盖所有的传递参数方式了。使用POSTMAN,可以方便的看到传递参数方式。
1.1GET
第一种,这种方式称呼为Query方式
1.2POST
共四种,分别为form-data、x-www-form-urlencoded、raw、binary,第五种和GET一样,不计算在内
2.实践
2.1 GET
2.1.1 Query
query支持的函数很多,Param函数需要说一下,其使用需要在router上配置
代码
1 | func paramTypeFunc(router *gin.Engine) { |
1 | /** |
调用
CODE: GET /paramtype/query/this is param?query=this is query&defaultQuery=this is defaultQuery&getQuery=this is getQuery&queryArray=this&queryArray=is&queryArray=queryArray&getQueryArray=this&getQueryArray=is&getQueryArray=getQueryArray&queryMap[1]=this&queryMap[2]=is&queryMap[3]=queryMap&getQueryMap[1]=this&getQueryMap[2]=is&getQueryMap[3]=getQueryMap
HTTP/1.1
Host: 127.0.0.1:8082
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: e0fdeb2e-78c2-c26d-03ad-a4a6715b3d66
输出
&{Query:this is query}
this is param
this is query
this is defaultQuery
this is getQuery true
[this is queryArray]
[this is getQueryArray] true
map[1:this 2:is 3:queryMap]
map[1:this 2:is 3:getQueryMap]
2.2 POST
2.2.1 form-data
form-data的获取正规正矩。 form-data就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来说明文件类型;content-disposition,用来说明字段的一些信息;
如果是文件,可以通过FormFile或者MultipartForm获取文件内容,FormFile获取一个,MultipartForm获取多个。使用SaveUploadedFile存储文件。
代码
1 | /** |
调用
CODE: POST /paramtype/postformdata HTTP/1.1
Host: 127.0.0.1:8082
Cache-Control: no-cache
Postman-Token: 83c078e3-b7de-d154-dda1-477cc4f2f450
Content-Type: multipart/form-data; boundary=—-WebKitFormBoundary7MA4YWxkTrZu0gW
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”postForm”
this is postForm
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”defaultPostForm”
this is defaultPostForm
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”getPostForm”
this is getPostForm
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”postFormArray”
this
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”postFormArray”
is
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”postFormArray”
postFormArray
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”getPostFormArray”
this
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”getPostFormArray”
is
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”getPostFormArray”
getPostFormArray
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”postFormMap[1]”
this
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”postFormMap[2]”
is
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”postFormMap[3]”
postFormMap
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”getPostFormMap[1]”
this
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”getPostFormMap[2]”
is
——WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”getPostFormMap[3]”
getPostFormMap
——WebKitFormBoundary7MA4YWxkTrZu0gW–
输出
&{GetPostForm:this is getPostForm}
this is postForm
this is defaultPostForm
this is getPostForm true
[this is postFormArray]
[this is getPostFormArray] true
map[1:this 2:is 3:postFormMap]
map[1:this 2:is 3:getPostFormMap]
2.2.2 x-www-form-urlencoded
x-www-form-urlencoded是application/x-www-from-urlencoded,将表单内的数据转换为键值对,&分隔。
当form表单的action为get时,浏览器用x-www-form-urlencoded的编码方式,将表单数据编码为
(name1=value1&name2=value2…),然后把这个字符串append到url后面,用?分隔,跳转到这个新的url。
当form表单的action为post时,浏览器将form数据封装到http body中,然后发到server。该格式不能提交文件。
代码
同form-data
调用
CODE: POST /paramtype/postformdata HTTP/1.1
Host: 127.0.0.1:8082
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 62ffa49a-e61f-0277-db62-dd9c727e182d
postForm=this+is+postForm&defaultPostForm=this+is+defaultPostForm&getPostForm=this+is+getPostForm&postFormArray=this&postFormArray=is&postFormArray=postFormArray&getPostFormArray=this&getPostFormArray=is&getPostFormArray=getPostFormArray&postFormMap%5B1%5D=this&postFormMap%5B2%5D=is&postFormMap%5B3%5D=postFormMap&getPostFormMap%5B1%5D=this&getPostFormMap%5B2%5D=is&getPostFormMap%5B3%5D=getPostFormMap
输出
同form-data
2.2.3 raw
可以上传任意格式的文本,包括text、json、xml、html等。
raw一般使用Bind和ShouldBind系列函数来获取数据,两者的区别是如果输入数据无效,Bind会将返回状态设置为400,并且中断,ShouldBind就没有这么狠。Bind和ShouldBind根据Content-Type来判断是json/xml/yaml格式,做对应解析。
ShouldBindUri和ShouldBindQuery使用起来有些技巧,代码中对此有标注。
代码
1 | router.POST("/paramtype/raw/:name", paramtype.Raw) |
1 | /** |
调用
CODE:
POST /paramtype/raw/I am raw name?query=I am query HTTP/1.1
Host: 127.0.0.1:8082
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 1c7f46a5-2ea2-36ac-1f9b-29dab2a90d62
{“id”:”1”,”text”:”I am raw json”}
输出
&{Id:1 Text:I am raw json}
&{Name:I am raw name}
&{Query:I am query}
2.2.4 binary
相当于Content-Type:application/octet-stream,从字面意思得知,只可以上传二进制数据,通常用来上传文件,由于没有键值,所以,一次只能上传一个文件。
Gin中没有找到相关的函数,文件上传使用的是multipart/form-data,如果大家有相关资料的话,可以告知我一下。
3.请求参数
参数
1 | GET: |
总结
Gin获取输入数据还是挺复杂的,这里简单总结一下:
- Get的使用Query、Param系列
- Post的form-data和x-www-form-urlencoded使用PostForm系列
- Get和Post的数据都可以用Bind、ShouldBind系列,不过结构体的tag需要写正确
- 文件上传使用form-data,通过函数FormFile或者MultipartForm
资料
1.https://geektutu.com/post/quick-go-gin.html Go Gin 简明教程
2.https://github.com/gin-gonic/gin 源码
3.https://gin-gonic.com/zh-cn/docs/ 中文文档
4.https://www.kancloud.cn/shuangdeyu/gin_book/949436 gin中文文档
5.https://www.kancloud.cn/adapa/gingolang/1124990 Gin框架入门到入土