简体   繁体   English

在Python中的POST请求中传递“+”字符

[英]Passing the '+' character in a POST request in Python

I am trying to do some automation in a Python script and I have run into a problem. 我试图在Python脚本中进行一些自动化,但我遇到了一个问题。 I am trying to do a POST to a server. 我正在尝试对服务器进行POST。

url = 'http://www.example.com'
params = {'arg0': 'value', 'arg1': '+value'}

f = urllib.urlopen(url, urllib.urlencode(params))
print f.read()

I have done a wireshark capture of the equivalent browser operation, where the second arg, arg1 is passed as +value , however when I do it with Python the + gets changed to %2B , ie 我已经完成了对等效浏览器操作的wireshark捕获,其中第二个arg, arg1作为+value传递,但是当我使用Python时, +变为%2B ,即

Line-based text data: application/x-www-form-urlencoded
arg0=value&arg1=%2Bvalue

when it should be: 应该是什么时候:

Line-based text data: application/x-www-form-urlencoded
arg0=value&arg1=+value

I have also used the Requests module and it seems to do the same thing. 我也使用了Requests模块,似乎做了同样的事情。

url = 'http://www.example.com'
params = {'arg0': 'value', 'arg1': '+value'}

f = requests.post(url, params)

Google is not your friend when you have a problem related to '+' as it seems to be a catch all for so much else. 当你遇到与'+'相关的问题时谷歌不是你的朋友,因为它似乎是其他许多问题。

The + character is the proper encoding for a space when quoting GET or POST data. 引用GET或POST数据时, +字符是空格的正确编码。 Thus, a literal + character needs to be escaped as well, lest it be decoded to a space on the other end. 因此,文字+字符也需要被转义,以免被解码到另一端的空间。 See RFC 2396, section 2.2 , section 3.4 and the HTML specification, application/x-www-form-urlencoded section : 请参阅RFC 2396, 第2.2节第3.4节HTML规范, application/x-www-form-urlencoded部分

Control names and values are escaped. 控制名称和值将被转义。 Space characters are replaced by `+', and then reserved characters are escaped as described in [RFC1738] , section 2.2. 空格字符由“+”替换,然后保留字符按[RFC1738]第2.2节中的描述进行转义。

If you are posting data to an application that does not decode a + character to a space but instead treats such data as literal plus signs instead, you need to encode your parameters yourself using the urllib.quote function instead, specifying that the + character is not to be encoded: 如果要将数据发布到不将+字符解码为空格的应用程序,而是将此类数据视为文字加符号,则需要使用urllib.quote函数urllib.quote编码参数,并指定+字符为不要编码:

import urllib
def urlencode_withoutplus(query):
    if hasattr(query, 'items'):
        query = query.items()
    l = []
    for k, v in query:
        k = urllib.quote(str(k), safe=' /+')
        v = urllib.quote(str(v), safe=' /+')
        l.append(k + '=' + v)
    return '&'.join(l)

Demo: 演示:

>>> urlencode_withoutplus({'arg0': 'value', 'arg1': '+value'})
'arg0=value&arg1=+value'

When using requests , you can simply pass in the result of the above function as the data value, but in that case you need to manually set the content type: 使用requests ,您只需将上述函数的结果作为data值传递,但在这种情况下,您需要手动设置内容类型:

requests.post(url, urlencode_withoutplus(query),
    headers={'Content-Type': 'application/x-www-form-urlencoded'})
urllib2.quote(' ')     # '%20'
urllib2.unquote('%20') # ' '

So why not just unquote the parameter part: 那么为什么不只是取消引用参数部分:

f = urllib.urlopen(url, urllib.unquote(urllib.urlencode(params)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM