qidao123.com技术社区-IT企服评测·应用市场
标题:
[flask]中心件
[打印本页]
作者:
卖不甜枣
时间:
2025-5-4 22:30
标题:
[flask]中心件
前言
中心件用于在哀求到达视图函数之前或响应返回给客户端之前执行一些操作,比如身份验证、日志记录、错误处理等。
方式1,使用钩子函数
from flask import Flask, request, Response
def DemoMiddleWare(app: Flask):
@app.before_request
def before_request1():
print("before_request")
@app.after_request
def after_request1(response: Response):
print(f"after_request, method: {request.method}, path: {request.path}")
return response
return app
app = Flask(__name__)
@app.get("/")
def hello():
return "Hello World!"
app = DemoMiddleWare(app)
if __name__ == "__main__":
app.run(debug=False)
复制代码
方式2,实现中心件类
from flask import Flask
from werkzeug.middleware.proxy_fix import ProxyFix
import time
class MyMiddleWare:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
data = {
"method": environ.get("REQUEST_METHOD", "NaN"),
"scheme": environ.get("wsgi.url_scheme", "NaN"),
"server_protocol": environ.get("SERVER_PROTOCOL", "NaN"),
"remote_addr": environ.get("REMOTE_ADDR", "NaN"),
"host": environ.get("HTTP_HOST", "NaN"),
"path": environ.get("PATH_INFO", "NaN"),
"user_agent": environ.get("HTTP_USER_AGENT", "NaN"),
}
# 自定义请求头都以 HTTP_* 开头
if header_ha := environ.get("HTTP_HA", ""):
data["header_ha"] = header_ha
# 处理 cookie
if cookie := environ.get("HTTP_COOKIE", ""):
data["cookie"] = cookie
start_time = time.time()
response = self.app(environ, start_response)
data["response_time"] = round((time.time() - start_time), 4)
print(data)
return response
class My2MiddleWare:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
print("This is middleware2, before request")
response = self.app(environ, start_response)
print("This is middleware2, after request")
return response
app = Flask(__name__)
# ProxyFix是werkzeug提供的一个中间件,当flask应用部署在反向代理器后面时,可以将反向代理器设置得X-Forwarded-*头信息
# 具体ProxyFix处理了哪些代理请求头可以参考ProxyFix的docstring
app.wsgi_app = ProxyFix(app.wsgi_app)
app.wsgi_app = MyMiddleWare(app.wsgi_app)
app.wsgi_app = My2MiddleWare(app.wsgi_app) # 添加第2个中间件
@app.get("/")
def hello():
return "Hello World!"
@app.get("/2")
def hello2():
return "Hello World!"
if __name__ == "__main__":
app.run(debug=False)
复制代码
上面示例代码只处理了哀求头等信息,偶然候可能还需要处理响应,比如获取响应码、设置响应头等。
from flask import Flask
import time
class MyMiddleWare:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
data = {
"method": environ.get("REQUEST_METHOD", "NaN"),
"scheme": environ.get("wsgi.url_scheme", "NaN"),
"server_protocol": environ.get("SERVER_PROTOCOL", "NaN"),
"remote_addr": environ.get("REMOTE_ADDR", "NaN"),
"host": environ.get("HTTP_HOST", "NaN"),
"path": environ.get("PATH_INFO", "NaN"),
"user_agent": environ.get("HTTP_USER_AGENT", "NaN"),
}
# 自定义请求头都以 HTTP_* 开头
if header_ha := environ.get("HTTP_HA", ""):
data["header_ha"] = header_ha
# 处理 cookie
if cookie := environ.get("HTTP_COOKIE", ""):
data["cookie"] = cookie
resp_status_code = None
resp_headers = []
def catching_start_response(status, headers, exc_info=None):
nonlocal resp_status_code, resp_headers
resp_status_code = status
headers.append(("X-Resp1", "OK")) # 添加自定义响应头
resp_headers = headers
return start_response(status, headers, exc_info)
start_time = time.time()
response = self.app(environ, catching_start_response)
data["status"] = resp_status_code
data["response_time"] = round((time.time() - start_time), 4)
print(data)
print(f"response headers: {resp_headers}")
return response
app = Flask(__name__)
app.wsgi_app = MyMiddleWare(app.wsgi_app)
@app.get("/")
def hello():
return "Hello World!"
@app.get("/2")
def hello2():
return "Hello World!"
if __name__ == "__main__":
app.run(debug=False)
复制代码
小结
两种方式实现中心件都行,不外用钩子函数会更方便点。假如想水代码行数,用中心件类也是不错的选择。
参考
Flask入门(九):Flask中心件
Flask官方文档
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4