【问题标题】:How to access wsgi params from a request inside a middleware and a flask request without side effect?如何从中间件内部的请求和烧瓶请求中访问 wsgi 参数而没有副作用?
【发布时间】:2012-10-12 16:08:40
【问题描述】:

在加载我的烧瓶应用程序之前,我需要从 wsgi 请求中读取一些值。如果我从 wsgi 请求中读取 url,一旦加载了烧瓶应用程序(在中间件运行之后),我就可以毫无问题地访问该文件。

但是,如果我尝试访问参数,一旦加载烧瓶应用程序,它似乎会删除发布数据。我什至用一个特殊的 Webob 请求来包装 wsgi 请求,以防止这种“读取一次”问题。

有谁知道如何在中间件中访问 wsgi 请求中的值,而不会对请求造成任何副作用,因此您可以在烧瓶应用程序中获取发布数据/文件数据?

from webob import Request

class SomeMiddleware(object):

    def __init__(self, environ):
        self.request = Request(environ)
        self.orig_environ = environ

    def apply_middleware(self):
        print self.request.url #will not do any harm
        print self.request.params #will cause me to lose data

这是我的烧瓶视图

    @app.route('/')
    def hello_world():
        from flask import request
        the_file = request.files['file']
        print "and the file is", the_file

【问题讨论】:

    标签: python python-2.7 flask wsgi webob


    【解决方案1】:

    据我所知,这是 WSGI 工作方式的限制。流只需要消耗一次PEP 3333333 只要求流支持read* 调用,不需要支持tell)。一旦流用尽,它就不能进一步“向内”重新流式传输到其他 WSGI 应用程序。查看 Werkzeug 文档的这两部分以了解更多信息:

    1. http://werkzeug.pocoo.org/docs/request_data/
    2. http://werkzeug.pocoo.org/docs/http/#module-werkzeug.formparser

    避免此问题的方法是将输入流 (wsgi.input) 包装在实现readreadline 方法的对象中。然后,只有当链中的最终应用程序实际尝试耗尽流时,您的方法才会运行。有关此模式的示例,请参阅 Flask's documentation on generating a request checksum

    话虽如此,您确定中间件是解决您问题的最佳方案吗?如果您需要根据请求的body 的内容执行某些操作(调度、日志记录、身份验证),最好将其作为应用程序的一部分,而不是独立的自己的应用。

    【讨论】:

      猜你喜欢
      • 2014-07-23
      • 2022-01-25
      • 2018-08-29
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      相关资源
      最近更新 更多