这是使用go
手写http
协议的第4篇,本篇我们将要实现获取请求报文提交的数据,目前我们已经支持2中请求方法: 1. GET
、2. POST
,我们这篇文章将在Get
请求上获取请求的数据。
Get中数据的提交方法
Get
方法提交数据一般提交数据像这个样子的,我们将其写为uri
如下:
http://127.0.0.1:8082/site?name=pdudo&site=juejin
像这样,我们其实提交了2个数据:
变量 | 值 |
name | pdudo |
site | juejin |
我们先不看url
编码和解码,我们假设,我们的url
不会涉及到解码的东西,那我们如何应该来写呢?
我们是不是得先将url
给拆解一下,拆解为URL
和 提交的参数 部分,例如我们的URI
为http://127.0.0.1:8082/site?name=pdudo&site=juejin
,则可以拆解为如下形式。
我们将uri
以第一个出现?
进行分割,将其分割为2个部门,前面一部分,我们称之为URL
,后面一部分称之为提交的参数。
完成一个简单的请求
这个代码,我们应该怎么写呢? 我们可以先定义能够接收参数的容器,我们直接加在RequestInfo
上即可。
那我们什么时候来判断呢? 我们可以在每次报文请求来的时候,如果请求方法为GET
,那我们就进行抓取参数,参数抓出来,我们放置到上述map
中,那么如何进行抓取呢,逻辑如我们上述所示,我们对URI
的第一个?
进行拆分,拆分之后,我们再进行按照&进行拆分,左边为key
,右边为value
,由于逻辑较为简单,就不画图了,我们直接看代码吧。
这样的话,就将参数写到了我们定义的map
中,我们在路由函数中,直接进行获取map
的数据即可,例如,我的URL``http://127.0.0.1:8082/site?name=pdudo&site=juejin
格式是这样的,我想获取name
和site
的值,我门在定义路由函数中,就可以这样写:
功能测试
我们可以来尝试一下
我们使用curl
来请求一下
web
日志为
我们也可以在浏览器尝试一下
额,我们发现乱码了,我们可以添加一个响应报文的首部行,名称为: Content-Type
值为: text/html;charset=utf-8
,我们尝试一下。
再次访问浏览器,则没有报错了
我们还需要URL解码
上述需求,我们写完了,结果真的如此么? 我们请求一个中文名称的url
呢,例如
我们代码也改了
但是实际上,输出为空,这是为什么呢? 好在我们输出了SampleHttp.HttpInfo
的值,我们可以看下解析的map
信息。
为什么会解析为这个样子呢? 不要急,我们找一个urldecode
的站点解析一下就可以了。
确实是我们需要的名称,那为什么会这样呢? 这个就要涉及到 url
编码了,在url
编码规则中,除了字母、数字、以及一些常用的符号在请求的时候,不会进行编码外,其他的,都会进行编码。编码会将字符解析为16进制的数据,然后再发到服务器,服务器接受后,需要解码,才能得到原始数据。
定义解码数据函数
在go
中,我们可以使用url.QueryUnescape()
来解码数据,我还专门去看了一下
例如:
url.QueryUnescape("%E5%90%8D%E5%AD%97")
例如,如上代码则返回解码后的数据: "名字"。
关于解码代码,我看了一下,没怎么看懂,不过我给借鉴了过来,写到我们自己的项目中,这里给一个假设,假设我们传入的URL
编码都是正确的。我们的解码代码可以编写如下:
我们再修改一下worker
函数传入的数据进行解密,
功能测试
我们测试下
查看我们打印的info
值,我们可以看到map
中已经变为中文了,赞。
总结
我们本次的功能,是解析GET
请求上发送的数据,大致可以分为2个部分,1. 截取数据部分 2. 进行URL
解码 ,这里其实有一个bug
,就是我们只解析了截取的数据部分,若我们路由带有中文的话,我们没办法解析的,不管怎么说,我们代码已经实现了,其代码已经上传到了gitee
: gitee.com/pdudo/Sampl… , 快来试试吧。