flask中间件

141 阅读2分钟

在 Flask 中,中间件通常是通过装饰器、上下文处理器或者更高级的 WSGI 应用中间件实现的。不过,由于 Flask 本身没有内置的“中间件”概念(像 Django 的中间件系统),我们通常使用装饰器或上下文处理器来模拟类似的功能。

不过,如果你想要的是一个真正的中间件(WSGI middleware),下面是一个示例,它检查请求的查询参数中是否包含 page 和 pagesize。如果没有,则返回一个 500 错误。

首先,我们创建一个 WSGI 中间件:

from functools import wraps  
from flask import Flask, jsonify, make_response  
  
class CheckParamsMiddleware:  
    def __init__(self, app):  
        self.app = app  
  
    def __call__(self, environ, start_response):  
        def custom_start_response(status, headers, exc_info=None):  
            start_response(status, headers, exc_info)  
  
        # 你可以从 environ 中获取查询参数,但这里为了简单起见,我们假设你已经有了它们  
        # 在 Flask 中,你通常会从 request.args 中获取查询参数  
        # 这里我们只是模拟这个过程  
        query_params = environ.get('QUERY_STRING', '')  
        params = {}  
        if query_params:  
            params = {k: v[0] for k, v in dict(parse_qs(query_params)).items()}  
  
        if 'page' not in params or 'pagesize' not in params:  
            return [b'Missing required parameters: page and pagesize'], [  
                ('Content-Type', 'text/plain'),  
                ('Content-Length', str(len(b'Missing required parameters: page and pagesize')))  
            ], 500  
  
        # 如果有必要的参数,继续处理请求  
        return self.app(environ, custom_start_response)  
  
# 注意:parse_qs 需要从 urllib.parse 导入,但为了简洁这里省略了  
# from urllib.parse import parse_qs  
  
# 创建一个 Flask 应用并应用中间件  
app = Flask(__name__)  
app.wsgi_app = CheckParamsMiddleware(app.wsgi_app)  
  
# 一个简单的路由,用于测试  
@app.route('/')  
def index():  
    return 'Hello, World!'  
  
if __name__ == '__main__':  
    app.run()

注意:上述示例中的 environ 字典通常不包含解析后的查询参数。为了简单起见,我假设你已经有了它们,并直接从 environ['QUERY_STRING'] 中获取。但在实际应用中,你可能需要使用 werkzeug.urls.url_decode 或其他方法来解析查询参数。

然而,在 Flask 应用中,更常见的做法是使用装饰器或请求预处理函数(@app.before_request)来执行此类检查:

from flask import Flask, jsonify, request  
  
app = Flask(__name__)  
  
@app.before_request  
def check_params():  
    if 'page' not in request.args or 'pagesize' not in request.args:  
        return jsonify({'error': 'Missing required parameters: page and pagesize'}), 500  
  
# ... 其他路由和代码 ...

这种方法更简单,也更符合 Flask 的习惯用法。