Python,Flask:如何为所有响应设置响应头

Python, Flask: How to set response header for all responses

我想将我所有的HTTP标头响应都设置为以下形式:

1
response.headers["X-Frame-Options"] ="SAMEORIGIN"

我检查了这个问题,但它只更改了一个特定控制器的标题。 我想更改所有标头,例如在" before_request"函数中,类似于以下逻辑。 我怎样才能做到这一点?

1
2
3
@app.before_request
def before_request():
    # response.headers["X-Frame-Options"] ="SAMEORIGIN"


将标头设置在@app.after_request()挂钩中,这时您具有一个响应对象以将标头设置为:

1
2
3
4
@app.after_request
def apply_caching(response):
    response.headers["X-Frame-Options"] ="SAMEORIGIN"
    return response

该挂钩运行时flask.request上下文仍然可用,因此此时您仍可以根据请求更改响应。


@app.after_request() hook不足以适合我的用例。

我的用例如下:我有一个谷歌云功能,我想为所有响应设置CORS标头。可能会有多个响应,因为我必须验证输入并在出现问题时返回,我必须处理数据并可能在出现故障时提早返回等。因此,我创建了一个如下的辅助函数:

1
2
3
4
5
6
# Helper function to return a response with status code and CORS headers
def prepare_response(res_object, status_code):
    response = flask.jsonify(res_object)
    response.headers.set('Access-Control-Allow-Origin', '*')
    response.headers.set('Access-Control-Allow-Methods', 'GET, POST')
    return response, status_code

因此,当我想返回一个响应(总是带有CORS标头)时,我现在可以调用此函数,并且不重复启用CORS所需的response.headers设置。


我们可以使用WSGI中间件为Python Flask应用程序中的所有响应设置响应标头

使用中间件在Flask应用程序上下文中设置响应标头的这种方式是线程安全的,可用于设置自定义和动态属性,读取请求标头,如果我们要从任何帮助程序类设置自定义/动态响应标头,则这特别有用。

文件:middleware.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import flask
from flask import request, g

class SimpleMiddleWare(object):
   """
    Simple WSGI middleware
   """


    def __init__(self, app):
        self.app = app
        self._header_name ="any_request_header"

    def __call__(self, environ, start_response):
       """
        middleware to capture request header from incoming http request
       """

        request_id_header = environ.get(self._header_name)  # reading all request headers
        environ[self._header_name] = request_id_header  

        def new_start_response(status, response_headers, exc_info=None):
           """
            set custom response headers
           """

            # set the above captured request header as response header
            response_headers.append((self._header_name, request_id_header))
            # example to access flask.g values set in any class thats part of the Flask app & then set that as response header
            values = g.get(my_response_header, {})
            if values.get('x-custom-header'):
                response_headers.append(('x-custom-header', values.get('x-custom-header')))
            return start_response(status, response_headers, exc_info)

        return self.app(environ, new_start_response)

从主类调用中间件

文件:main.py

1
2
3
4
5
6
7
from flask import Flask
import asyncio
from gevent.pywsgi import WSGIServer
from middleware import SimpleMiddleWare

    app = Flask(__name__)
    app.wsgi_app = SimpleMiddleWare(app.wsgi_app)