Модуль запросов Python отправляет строку JSON вместо строки параметра x-www-form-urlencoded param

У меня создалось впечатление, что POSTS, использующие спецификации x-www-form-urlencoded, должны отправить URL-строку с кодировкой URL в тело сообщения. Однако, когда я это делаю,

data = json.dumps({'param1': 'value1', 'param2': 'value2'})
Requests.post(url, data=data)

Тело запроса на принимающей стороне выглядит следующим образом:

{"param1": "value1", "param2": "value2"}

Но я ожидал получить этот

param1=value1&param2=value2

Как я могу получить запросы для отправки данных во второй форме?

Ответ 1

Причина, по которой вы получаете JSON, заключается в том, что вы явно вызываете json.dumps для генерации строки JSON. Просто не делайте этого, и вы не получите строку JSON. Другими словами, измените свою первую строку на это:

data = {'param1': 'value1', 'param2': 'value2'}

Как объясняют документы, если вы передадите dict в качестве значения data, он будет закодирован в форме, а если вы передадите строку, она будет отправлена как есть.


Например, в одном окне терминала:

$ nc -kl 8765

В другой:

$ python3
>>> import requests
>>> d = {'spam': 20, 'eggs': 3}
>>> requests.post("http://localhost:8765", data=d)
^C
>>> import json
>>> j = json.dumps(d)
>>> requests.post("http://localhost:8765", data=j)
^C

В первом терминале вы увидите, что первое тело запроса это (и Content-Type application/x-www-form-urlencoded):

spam=20&eggs=3

... в то время как второй это (и не имеет Content-Type):

{"spam": 20, "eggs": 3}

Ответ 2

Важно добавить, что это не работает для вложенного JSON Итак, если у вас есть

# Wrong
data = {'param1': {'a':[100, 200]},
        'param2': 'value2',
        'param3': False}

# You have to convert values into string:
data = {'param1': json.dumps({'a':[100, 200]}),
        'param2': 'value2',
        'param3': json.dumps(False)}