处理请求数据 — Werkzeug 文档
处理请求数据
Web 开发最重要的规则是“不要信任用户”。 对于输入流上的传入请求数据尤其如此。 对于 WSGI,这实际上比您预期的要困难一些。 因此,Werkzeug 为您包装了请求流,以免您遇到最突出的问题。
输入流上缺少 EOF 标记
输入流没有文件结束标记。 如果您在 wsgi.input 流上调用 read()
方法,则会导致您的应用程序挂在符合标准的服务器上。 这实际上是故意的,但很痛苦。 Werkzeug 通过将输入流包装在一个特殊的 LimitedStream
中来解决这个问题。 输入流在请求对象上公开为 stream
。 这是一个空流(如果表单数据已被解析)或包含输入流内容的有限流。
Werkzeug 何时解析?
Werkzeug 在以下情况下解析传入的数据:
- 您访问
form
、files
或stream
,请求方法为 POST 或 PUT。 - 如果您调用
parse_form_data()
。
这些调用不可互换。 如果调用 parse_form_data()
,则不得使用请求对象,或者至少不得使用触发解析过程的属性。
如果在解析之前从 wsgi.input 流中读取,也是如此。
一般规则: 保留 WSGI 输入流。 特别是在 WSGI 中间件中。 使用解析函数或请求对象。 不要将多个 WSGI 实用程序库混合用于表单数据解析或任何其他适用于输入流的东西。
它是如何解析的?
标准 Werkzeug 解析行为处理三种情况:
- 输入内容类型为 multipart/form-data。 在这种情况下,
stream
将为空,form
将包含常规 POST / PUT 数据,files
将包含常规数据上传的文件为FileStorage
对象。 - 输入内容类型为 application/x-www-form-urlencoded。 然后
stream
将为空,而form
将包含常规的 POST / PUT 数据,而files
将为空。 - 输入内容类型都不是它们,
stream
指向一个LimitedStream
,其中包含用于进一步处理的输入数据。
关于 get_data
方法的特别说明:调用它会将完整的请求数据加载到内存中。 只有在设置了 max_content_length
时,这才是安全的。 您也可以 ' 读取流 或 调用 get_data()
。
限制请求数据
为避免成为 DDOS 攻击的受害者,您可以设置最大可接受的内容长度和请求字段大小。 BaseRequest
类有两个属性:max_content_length
和 max_form_memory_size
。
第一个可用于限制总内容长度。 例如,通过将其设置为 1024 * 1024 * 16
,请求将不会接受超过 16MB 的传输数据。
由于某些数据无法移动到硬盘(常规发布数据)而临时文件可以,因此您可以设置第二个限制。 max_form_memory_size
限制了 POST 传输的表单数据的大小。 通过将其设置为 1024 * 1024 * 2
,您可以确保所有内存存储字段的大小不超过 2MB。
但是,如果使用的 stream_factory 返回内存文件,则 不会 影响内存中存储的文件。
如何扩展解析?
现代 Web 应用程序传输的不仅仅是多部分表单数据或 url 编码数据。 要扩展功能,子类 BaseRequest
或 Request
并添加或扩展方法。
已经有一个提供 JSON 解析的 mixin:
其基本实现如下所示: