Flask-CORS 不适用于 WSGI 中间件返回的响应

Flask-CORS does not apply to responses returned by WSGI middleware

我有一个使用 Flask-CORS 的 Flask 应用程序,以及一个 returns 自定义响应的 WSGI 中间件,而不是某些路由的 Flask 应用程序。对于响应,未应用中间件 returns、Flask-CORS,因此我不得不手动将 CORS headers 应用到该响应。

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

    def __call__(self, environ, start_response):
        request = Request(environ)

        if request.path == "/foo":
            res = Response("...", mimetype="application/json", status=403)
            # flask-cors is not applied, so I set headers manually
            res.access_control_allow_credentials = True
            res.access_control_allow_origin = "*"
            res.access_control_allow_methods = ["GET", "PUT", "DELETE", "PATCH", "OPTIONS", "POST", "HEAD"]
            return res(environ, start_response)

        return self.app(environ, start_response)  # flask-cors works here

app = Flask(__name__)
app.wsgi_app = Middleware(app)
CORS(app)

我尝试颠倒应用中间件和 Flask-CORS 的顺序,但这并没有改变它。

app = Flask(__name__)
CORS(app)
app.wsgi_app = Middleware(app)

我不想重复 Flask-CORS 所做的事情。如何将 Flask-CORS 应用于中间件的响应?

Flask-CORS 是 Fl​​ask 扩展。它工作在 Flask 应用层,即它对到达 Flask 应用程序的请求进行操作。应用于应用程序的中间件发生在 Flask 应用程序周围,即 Flask 扩展看到的上方层。您注册扩展与应用中间件的顺序与此无关,它们位于 WSGI 调用堆栈的不同层。

当请求进入时,您的中间件决定尽早 return 响应并且从不调用它包装的 Flask 应用程序,因此 Flask 应用程序不会执行任何内容,包括 Flask-CORS 扩展在上面。您不能将 Flask-CORS 应用于中间件响应,因为它不在同一层工作。

如果您需要在中间件 return 的响应中使用 CORS headers,则需要按照您的操作自行设置。如果你想避免这种重复,你需要在 Flask 中做所有事情,或者编写一个中间件来围绕这个其他中间件而不是 Flask-CORS 扩展执行 CORS。

要在 Flask 堆栈中编写等效的中间件,以便 Flask-CORS 扩展影响您生成的响应,请使用 before_requestbefore_request 函数可以 return 响应(或中止)以提前结束视图处理并继续响应处理。

from flask import request, Response

@app.before_request
def some_users_403():
    if request.path == "/foo":
        return Response("...", status=403)