33

外部 API をいじっているときに、この問題に遭遇しました。本文データをディクショナリとしてリクエストに直接送信していたところ、400 エラーが発生していました。

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 Requests ライブラリを使用していますが、別の投稿では、パラメーターをリクエスト オブジェクトにエンコードする必要はないと示唆しているようです: https://stackoverflow.com/a/14804320/1012040

「GET/POST かどうかに関係なく、パラメーターを再度エンコードする必要はありません。引数として辞書を使用するだけでよいのです。」

シリアル化は必要ないようですか?

私のリクエストオブジェクト:

response = requests.post(url, data=data, headers=headers)
4

2 に答える 2

58

どうやらあなたのAPIには、フォームエンコードされたデータではなく、JSONエンコードされたデータが必要です。dictパラメータとしてa を渡すdataと、データはフォーム エンコードされます。文字列 ( の結果などjson.dumps) を渡す場合、データはフォーム エンコードされません。

リクエスト ドキュメントからのこの引用を検討してください。

通常、HTML フォームのように、フォームにエンコードされたデータを送信します。これを行うには、辞書を data 引数に渡すだけです。リクエストが行われると、データの辞書は自動的にフォーム エンコードされます。

フォーム エンコードされていないデータを送信したい場合がよくあります。辞書の代わりに文字列を渡すと、そのデータは直接投稿されます。

たとえば、GitHub API v3 は、JSON でエンコードされた POST/PATCH データを受け入れます。

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

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

参照:

于 2013-03-29T03:06:18.560 に答える
1

構文的には同じように見えますが、違いがあります。JSON はシリアライズされたオブジェクトの文字列表現です。この場合、Python dict. この例では、シリアル化されたデータを文字列の形式で送信する必要があるため、シリアル化を実行するには json.dumps が必要です。

編集

質問へのコメントで示唆されているように、使用されている API に関連していますが、それでもオブジェクトをネットワーク経由で送信する途中でシリアライゼーションを行う必要があります。

于 2013-03-28T23:51:19.037 に答える