Li RUONAN


一枚行走在前端道路上的程序媛 ~~


request请求(Tornado)

最近在定位一个棘手的bug,遇到了不同的request请求提交方式,于是在这里写写两种方式的区别:

form表单提交request

  1. header配置如下:Content-Type:application/x-www-form-urlencoded;charset=UTF-8
  2. form的数据格式, 例如:a=1&b=2&c=3

json提交request

  1. header配置如下:Content-Type:application/json;charset=UTF-8
  2. json的数据格式, 例如:{“a”:1,”b”:2,”c”:3}

背景:UI自动化Agent服务框架Tornado(Python2.7)

  • Tornado框架默认采用 application/x-www-form-urlencoded 数据编码格式提交request请求,由于部分场景的数据用json传递,于是公司的agent服务代码无法解析request.body,导致报错。
  • 猜测到这个原因之后,没有着急去改bug,而是先去排查了环境因素。极路由上的Nginx转发有没有导致丢数据,agent服务在beta环境和mock环境都是这样吗?首先,使用fiddler(Charles)在不同环境抓包,查看了post请求的request和response,排除了环境因素;其次,Nginx也只是做了最简单的通配符location的设计,排除了极路由因素。最终,确定bug的产生与headers参数有关。

修复bug:

1. 将代码中的post函数单独拿出来,对其request,response参数进行debug。
    当agent请求beta环境时,若headers参数Content-Type:application/json,
    agent服务仍然采用form的解析方式,因此对resquest.body解析不对。
    于是,我添加了初始化body参数的方法。

2. 方法如下:
    
1
2
3
4
5
6
7
8
9
10
11
12
# 初始化body参数 #
def init_body_params(self):
body = dict()
bodys = self.request.body
self.flag = 1
if bodys.startwith("{"):
self.flag = 0 # 此处作标记,send_post时需要继续判断json
body = json.loads(bodys.decode('utf-8'))
else:
for k in self.request.body_arguments:
body[k] = self.request.body_arguments[k][0]
return body
3. 在send_post方法中针对不同headers情况,body做封装后再发post请求
1
2
3
4
5
6
7
8
9
10
11
12
13
def send_post(self, body):
for x in self.request.headers:
print "header %s: %s" % (x, self.request.headers.get(x))

if self.flag == 0:
body = self.request.body
else:
body = urllib.urlencode(body)

# self.url, self.headers, handleReponse 省略
http_client = tornado.httpclient.AsyncHTTPClient()
request = tornado.httpclient.HTTPRequest(self.url, method = 'POST', headers = self.headers, body = body)
http_client = http_client.fetch(request, callback = handlResponse)
4. 简要说明一下, fetch请求。 * AsyncHTTPClient() # tornado的优势,异步HTTP客户端; * 一般先使用HTTPRequest封装好一个request主体,再使用fetch发送post请求。