将JSON字符串作为POST请求发送

4

rocksteady的解决方案可行

他最初确实提到了字典。但以下代码使用requests发送JSON字符串也非常有效:

import requests

headers = {
  'Authorization': app_token
}
url = api_url + "/b2api/v1/b2_get_upload_url"
content = json.dumps({'bucketId': bucket_id})

r = requests.post(url, data = content, headers = headers)

我正在使用一个API,需要我将JSON作为POST请求发送以获取结果。问题是Python 3不允许我这样做。

以下Python 2代码正常工作,实际上它是官方示例:

request = urllib2.Request(
    api_url +'/b2api/v1/b2_get_upload_url',
    json.dumps({ 'bucketId' : bucket_id }),
    headers = { 'Authorization': account_authorization_token }
)
response = urllib2.urlopen(request)

然而,在Python 3中使用此代码会导致其抱怨数据无效:
import json
from urllib.request import Request, urlopen
from urllib.parse import urlencode

# -! Irrelevant code has been cut out !-

headers = {
  'Authorization': app_token
}
url = api_url + "/b2api/v1/b2_get_upload_url"

# Tested both with encode and without
content = json.dumps({'bucketId': bucket_id}).encode('utf-8')

request = Request(
  url=url,
  data=content,
  headers=headers
)

response = urlopen(req)

我尝试使用urlencode(), 正如你应该做的那样。但是这会导致Web服务器返回400状态码,因为它期望纯JSON数据。 即使纯JSON数据无效,我也需要以某种方式强制Python发送它。 编辑:根据要求,这里是我得到的错误。由于这是一个flask应用程序,因此以下是调试器的屏幕截图: 屏幕截图 添加.encode('utf-8')会给我一个“预期字符串或缓冲区”的错误。 编辑2带有.encode('utf-8')的调试器的屏幕截图

你不应该使用urlencode;那是用于表单编码数据的,但你正在发送JSON。但如果你遇到错误,你应该发布它。 - Daniel Roseman
服务器不支持Unicode字符"\u2119"。如果想要测试其他内容,请创建演示服务器。 - dsgdfg
看一下这个链接:json.dumps vs. flask.jsonify 或许有帮助。 - rocksteady
你发布的错误没有.encode('utf-8')调用。加上后还有错误吗? - Gary van der Merwe
@rocksteady 这看起来很有趣。但是我尝试手动设置内容头部却没有成功,它给出了相同的错误。这段代码也没有导入 Flask。它是被 Flask 应用程序使用的模块 - 我会继续研究这个问题,可能是我忽略了与内容头相关的某些东西。 - Quad
@GaryvanderMerwe 这就在下面提到了。我现在没有电脑。但是请在大约5分钟后回来,当我有电脑时,我会尽量添加一张图片,以便更方便地了解详情。 - Quad
1个回答

3

由于我有一个类似的应用程序在运行,但客户端仍然缺失,所以我自己尝试了一下。正在运行的服务器来自以下练习:

Miguel Grinberg - 设计使用Flask的RESTful API

这就是为什么它使用身份验证。

但是有趣的部分:使用requests,您可以将字典保持原样。

看看这个:

username = 'miguel'
password = 'python'

import requests
content = {"title":"Read a book"}

request = requests.get("http://127.0.0.1:5000/api/v1.0/projects", auth=(username, password), params=content)
print request.text

看起来它能正常工作 :)

更新1:

使用requests.post(...)发送POST请求,这里有一个很好的描述:python requests

更新2:

为了完成答案:

requests.post("http://127.0.0.1:5000/api/v1.0/projects", json=content)

发送json字符串。

json是请求的有效参数,内部使用json.dumps()...


2
字典不是问题。它们工作得很好,我遇到的问题是发送一个不属于任何字典或列表的单个JSON字符串。但既然你建议了,我也可以使用字符串测试请求。 - Quad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接