python urllib2请求在POST数据前添加换行符

1 投票
1 回答
2044 浏览
提问于 2025-04-18 03:02

我有一个简单的Python(2.7.5)脚本,它使用urllib2将数据发送到服务器上的一个Django(1.6.2)应用。当请求到达服务器时,发送的一个值被截断了,还有一个字段名前面多了个CR/LF的前缀。这看起来像是编码的问题,但我不知道该怎么解决。

这个Python脚本是这样向服务器发送数据的:

auth = 'Basic ' + base64.encodestring('%s:%s' % (user, pwd))
header = {'Authorization': auth }

data = {
    'status': 'TEST',
    'activity_code': 'TEST',
    'sw_version': 'TEST',
    'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
data = urllib.urlencode(data)

request = urllib2.Request(url, data, header)
response = urllib2.urlopen(request)
result = json.loads(response.read())
print 'result = ', str(result), '\n'

在服务器上,有一个Django应用用来处理这个请求,处理方式是这样的:

data = request.POST.copy()
error = {}

try:
    required = ['activity_code', 'timestamp', 'sw_version', 'status']
    for field in required:
        assert len(data.get(field)) > 0
except:
    error['message'] = 'required field is missing (' + field + ')'
    error['debug'] = data

if error:
    content = json.dumps(error, cls=DjangoJSONEncoder)
    return HttpResponse(content, content_type='application/json')

这是脚本在收到服务器响应后的输出:

result = {u'debug': {u'timestamp': u'2014-04-16 14:22:15', u'\r\nstatus': u'TEST', u'activity_code': u'TEST', u'sw_version': u'TE'}, u'message': u'required field is missing (status)'}

注意到status字段名前面不知怎么多了个CR/LF,而sw_version的值从'TEST'变成了'TE',被截断了。

这到底是怎么回事呢??

1 个回答

2

你没有打印出你的 header 变量的值,但你描述的问题可能是因为 header 的值以 \r\n 结尾。下面是原因:

一个 HTTP 请求的头部应该以两个 \r\n(也叫 CRLF)结束,之后才是 POST 数据。urllib2 模块不会检查你的头部值里是否有 CRLF。如果有的话,服务器会认为头部在一个 CRLF 处“过早”结束。这会导致 POST 数据从你实际头部结束标记的最后一个 CRLF 开始。这样一来,内容长度头部(计算你原始 POST 数据的长度)就会把 POST 数据截断两个字符。

所以我建议你再仔细检查一下你的头部信息。

撰写回答