如何访问 Flask 的 WSGI 中间件中的响应内容?

How do I access response content in WSGI middleware for Flask?

我想为 Flask 编写中间件来更改 HTML 响应中的数据。在 Django 中,我可以使用 Middleware class 并访问 response.content 来更改内容。如何在 Flask 或 WSGI 中间件中访问和修改响应内容?

class Middleware:
    def __init__(self, get_response=None):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        self.process_response(request, response)
        return response

    def process_response(self, request, response):
        html = response.content.decode('utf-8')
        # do stuff with the HTML
        return response

Flask 中 Django 的“中间件”最接近的等价物是 Flask 的 before_requestafter_request 函数。他们可以在与 Flask 应用程序相同的层自省和修改请求和响应。

要获取响应内容,请在 after_request 函数中访问 response.get_data(as_text=True)。该函数必须 return 一个响应,直接修改 response.data 或使用 app.make_response(new_data) 创建一个新响应。您还可以修改响应的任何其他属性。

from flask import request

@app.before_request
def modify_incoming():
    if {some test on request}:
        ...

    # can return app.make_response() to end the request early

@app.after_request
def modify_outgoing(response):
    html = response.get_data(as_text=True)
    response.data = {modify html}
    return response

WSGI 中间件(可以与任何 WSGI 框架一起使用,包括 Django)位于应用程序本身之外的一层,因此您需要使用 WSGI 规范提供的基本接口。 Werkzeug 的实用程序可能在这个较低层有用。

class ModifyHTMLMiddleware:
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        # can modify environ to affect what the wrapped application sees
        app_iter = self.app(environ, start_response)
        # decode and encode need to use the appropriate codec
        html = b"".join(app_iter).decode("utf8")
        # modify html
        return [html.encode("utf8")]