2013-03-28 74 views
11

我在使用外部API時遇到了這個問題。我送我的身體數據字典直入請求,並漸漸400錯誤:爲什麼HTTP POST請求主體需要在Python中被JSON支持?

data = { 
    "someParamRange": { 
    "to": 1000, 
    "from": 100 
    }, 
    "anotherParamRange": { 
    "to": True, 
    "from": False 
    } 
} 

當我加入了json.dumps包裝,它的工作原理:

data = json.dumps({ 
    "someParamRange": { 
    "to": 1000, 
    "from": 100 
    }, 
    "anotherParamRange": { 
    "to": True, 
    "from": False 
    } 
}) 

我並不完全理解爲什麼這是必要的,因爲字典和JSON對象在語法上是相同的。有人能幫我理解幕後的情況嗎?

爲了完整起見,這裏有我的頭:

headers = {'API-KEY': 'blerg', 'Accept-Encoding': 'UTF-8', 'Content-Type': 'application/json', 'Accept': '*/*', 'username': 'user', 'password': 'pwd'} 

編輯:

我沒有提到這一點早,但現在我覺得這可能是相關的。我正在使用Python請求庫,另一篇文章似乎建議您不應該將參數編碼到請求對象:https://stackoverflow.com/a/14804320/1012040

「無論GET/POST是否再次需要編碼參數,它只需要一本字典作爲論據,並且很好走。「

似乎不需要序列化?

我請求對象:

response = requests.post(url, data=data, headers=headers) 
+1

你應該發佈你的代碼的其餘部分..我可以做一個http api,其中任何一個都可以等效。 – cwa

+0

它不是一個公共API,o/w我會:(你是說這可能只是特定API的函數,而不是一般的HTTP請求? – acpigeon

+1

我建議讀一讀關於對象序列化的知識。 '將對象序列化,以便它可以作爲數據流發送,實質上直接插入對象將發送一個二進制數據流,服務器將不知道如何解碼。 – PhD

回答

21

顯然你的API需要JSON編碼而不是表單編碼數據。當您將dict作爲參數data傳入時,數據將進行表格編碼。當你傳遞一個字符串(如json.dumps的結果)時,數據不是形式編碼的。

考慮這個報價從請求文檔:

通常情況下,你要發送某種形式的編碼數據 - 很像一個HTML表單。要做到這一點,只需將字典傳遞給數據參數即可。您的數據字典將在請求完成時自動進行表格編碼。

有很多次你想要發送的數據不是形式編碼的。如果您傳入字符串而不是字典,則會直接發佈該數據。

例如,GitHub的API第3版接受JSON編碼POST/PATCH數據:

>>> import json 
>>> url = 'https://api.github.com/some/endpoint' 
>>> payload = {'some': 'data'} 

>>> r = requests.post(url, data=json.dumps(payload)) 

參考文獻:

+3

這對我來說不起作用,因爲它必須添加以下頭文件:headers = {''Content-Type':'application/json'} – redobot

1

儘管它們似乎syntatically itentical是有區別的:JSON是序列化的對象的字符串表示;在這種情況下,Python字典。在這個例子中,您需要以字符串的形式發送序列化的數據,因此執行序列化需要執行json.dumps。

編輯

正如意見的問題提出它是相對於舊的API,但仍然系列化必須沿途某處做了通過網絡發送的對象。

相關問題