为什么content-type为application/x-www-form-urlencoded时请求正文为空?

Why is the request body blank when the content-type is application/x-www-form-urlencoded?

我收到了内容类型为 application/x-www-form-urlencoded 的请求。当我尝试使用 cherrypy.request.body.read() 读取请求正文时,结果是 b''.

我似乎能够使用以下任何一个访问请求表单参数:

cherrypy.request.params

cherrypy.request.body.params

cherrypy.request.body.request_params

但这对我的用例来说很不方便,我希望无论内容类型如何都能获得原始请求正文。另外,上面的 3 给了我一本字典,这不是请求正文中的确切格式。有没有办法用 cherrypy 做到这一点?或者这个功能是隐藏的?

不确定您不使用与定义的 Content-Type 相对应的已经解析的正文来尝试完成什么...但是您可以自己配置处理请求的正文:cherrypy.request.process_request_body = False并阅读正文:

cherrypy.request.rfile.read(cherrypy.request.headers['Content-Length'])

有关详细信息,请参阅:https://github.com/cherrypy/cherrypy/blob/master/cherrypy/_cprequest.py#L292-L315

url相关部分的片段:

rfile = None
"""
If the request included an entity (body), it will be available
as a stream in this attribute. However, the rfile will normally
be read for you between the 'before_request_body' hook and the
'before_handler' hook, and the resulting string is placed into
either request.params or the request.body attribute.
You may disable the automatic consumption of the rfile by setting
request.process_request_body to False, either in config for the desired
path, or in an 'on_start_resource' or 'before_request_body' hook.
WARNING: In almost every case, you should not attempt to read from the
rfile stream after CherryPy's automatic mechanism has read it. If you
turn off the automatic parsing of rfile, you should read exactly the
number of bytes specified in request.headers['Content-Length'].
Ignoring either of these warnings may result in a hung request thread
or in corruption of the next (pipelined) request.
"""

process_request_body = True
"""
If True, the rfile (if any) is automatically read and parsed,
and the result placed into request.params or request.body.
"""

body = None
"""
If the request Content-Type is 'application/x-www-form-urlencoded'
or multipart, this will be None. Otherwise, this will be an instance
of :class:`RequestBody<cherrypy._cpreqbody.RequestBody>` (which you
can .read()); this value is set between the 'before_request_body' and
'before_handler' hooks (assuming that process_request_body is True."""