我尝试在我的项目中使用falcon包。问题是我没有找到从HTTP post请求获取正文数据的方法。
我使用了示例中的代码,但req.stream.read()
没有按预期返回JSON。
代码是:
raw_json = req.stream.read()
result.json(raw_json, encoding='utf-8')
resp.body = json.dumps(result_json, encoding='utf-8')
如何获取POST数据?
谢谢你的帮助
很少挖掘问题导致以下linked issue on github。它声明falcon框架至少在其0.3版本中并且与Python 2一起工作时,如果它们被适当地转义,则不会将数据“POSTed”解析为字符串。我们可以使用有关您尝试通过POST请求发送的数据以及发送的格式的更多信息,例如,它是作为简单文本发送,还是使用Header Information Content-Type:application / json,或者如果是通过HTML表单。
虽然问题的确切问题不明确,我仍然可以建议尝试使用bounded_stream
而不是stream
,如:
raw_json = req.bounded_stream.read()
result.json(raw_json, encoding='utf-8')
resp.body = json.dumps(result_json, encoding='utf-8')
官方文档建议使用bounded_stream
,其中不确定条件如Content-Length undefined或0,或者如果标题信息完全丢失。
bound_stream在官方falcon documentation中描述如下。
类似于文件的流包装器,用于规范不同WSGI服务器使用的本机输入对象之间的某些差异。特别是,bounded_stream知道正文的预期Content-Length,并且永远不会阻止越界读取,假设客户端在将数据传输到服务器时没有停顿。
Falcon接收HTTP请求数据作为缓冲区对象,由WSGI包装器传递,它从客户端接收数据,并且由于性能原因,它可能无法在数据之上运行正确的解析以转换为更有用的数据结构。
你正在寻找的领域有点混乱,但它是req.media:
返回请求流的反序列化形式。调用时,它将尝试使用Content-Type标头以及通过
falcon.RequestOptions
配置的媒体类型处理程序反序列化请求流。
如果请求是JSON,req.media
已经包含python dict。
我在falcon框架中添加了request.py中的更改来解析application / x-www-form-urlencoded和multipart / from-data。我已经提出拉动请求 - https://github.com/falconry/falcon/pull/1236但它还没有合并到主人。检查一下 - https://github.com/branelmoro/falcon
我添加了新代码来解析POST,PUT和DELETE application / x-www-form-urlencoded和multipart / form-data。文本字段将在req.form_data字典中可用,上载文件缓冲区流将在req.files字典中可用。
我希望这有助于分别访问POST和GET参数,我们也可以上传文件。改变的好处是它不会将整个上传的文件加载到内存中。
下面是示例代码,用于说明如何使用POST,PUT和DELETE application / x-www-form-urlencoded和multipart / form-data:
import falcon
class Resource(object):
def on_post(self, req, resp):
# req.form_data will return dictionary of text field names and their values
print(req.form_data)
# req.form_data will return dictionary of file field names and
# their buffer class FileStream objects as values
print(req.files)
# support we are uploading a image.jpg in `pancard` file field then
# req.files["pancard"] will be FileStream buffer object
# We can use set_max_upload_size method to set maximum allowed
# file size let say 1Mb = 1*1024*1024 bytes for this file
req.files["pancard"].set_max_upload_size(1*1024*1024)
# We can use uploadto method to upload file on required path (Note: absolute filepath is required)
# This method returns boolean - `True` on successful upload
# and if upload is unsuccessful then it returns `False` and sets error on failure.
path = "/tmp/" + req.files["pancard"].name
response = req.files["pancard"].uploadto("/tmp/" + path)
print(response)
# Once file is uploaded sucessfully, we can check it's size
print(req.files["pancard"].size)
# If file is not uploaded sucessfully, we can check it's error
print(req.files["pancard"].error)
resp.body = "Done file upload"
resp.status = falcon.HTTP_200
# falcon.API instances are callable WSGI apps
app = falcon.API()
things = Resource()
# things will handle post requests to the '/post_path' URL path
app.add_route('/post_path', things)
如果您有任何疑问,请告诉我。
非常感谢Ryan(和Prateek Jain)的回答。
解决方案就是放app.req_options.auto_parse_form_urlencoded=True
。例如:
import falcon
class ThingsResource(object):
def on_post(self, req, resp):
value = req.get_param("value", required=True)
#do something with value
app = falcon.API()
app.req_options.auto_parse_form_urlencoded=True
things = ThingsResource()
app.add_route('/things', things)
在猎鹰2中,如果你使用json类型,请使用req.media
例如:
import falcon
from json import dumps
class Resource(object):
def on_post(self, req, resp, **kwargs):
result = req.media
# do your job
resp.body = dumps(result)
api = falcon.API()
api.add_route('/test', Resource())
到目前为止...对我来说bounded_stream.read()和stream.read()都将发布的数据作为str类型。到目前为止,我只找到了解决问题的方法:
def on_post(self, req, resp):
posted_data = json.loads(req.stream.read())
print(str(type(posted_data)))
print(posted_data)
收到发布的数据后,将字符串加载到json dict是我能想到的唯一解决方案