How do I set response headers in Flask?

前端 未结 5 1548
北海茫月
北海茫月 2020-11-27 14:32

This is my code:

@app.route(\'/hello\', methods=[\"POST\"])
def hello():
    resp = make_response()
    resp.headers[\'Access-Control-Allow-Origin\'] = \'*\'         


        
相关标签:
5条回答
  • 2020-11-27 14:54

    You can do this pretty easily:

    @app.route("/")
    def home():
        resp = flask.Response("Foo bar baz")
        resp.headers['Access-Control-Allow-Origin'] = '*'
        return resp
    

    Look at flask.Response and flask.make_response()

    But something tells me you have another problem, because the after_request should have handled it correctly too.

    EDIT
    I just noticed you are already using make_response which is one of the ways to do it. Like I said before, after_request should have worked as well. Try hitting the endpoint via curl and see what the headers are:

    curl -i http://127.0.0.1:5000/your/endpoint
    

    You should see

    > curl -i 'http://127.0.0.1:5000/'
    HTTP/1.0 200 OK
    Content-Type: text/html; charset=utf-8
    Content-Length: 11
    Access-Control-Allow-Origin: *
    Server: Werkzeug/0.8.3 Python/2.7.5
    Date: Tue, 16 Sep 2014 03:47:13 GMT
    

    Noting the Access-Control-Allow-Origin header.

    EDIT 2
    As I suspected, you are getting a 500 so you are not setting the header like you thought. Try adding app.debug = True before you start the app and try again. You should get some output showing you the root cause of the problem.

    For example:

    @app.route("/")
    def home():
        resp = flask.Response("Foo bar baz")
        user.weapon = boomerang
        resp.headers['Access-Control-Allow-Origin'] = '*'
        return resp
    

    Gives a nicely formatted html error page, with this at the bottom (helpful for curl command)

    Traceback (most recent call last):
    ...
      File "/private/tmp/min.py", line 8, in home
        user.weapon = boomerang
    NameError: global name 'boomerang' is not defined
    
    0 讨论(0)
  • 2020-11-27 15:03

    We can set the response headers in Python Flask application using Flask application context using flask.g

    This way of setting response headers in Flask application context using flask.g is thread safe and can be used to set custom & dynamic attributes from any file of application, this is especially helpful if we are setting custom/dynamic response headers from any helper class, that can also be accessed from any other file ( say like middleware, etc), this flask.g is global & valid for that request thread only.

    Say if i want to read the response header from another api/http call that is being called from this app, and then extract any & set it as response headers for this app.

    Sample Code: file: helper.py

    import flask
    from flask import request, g
    from multidict import CIMultiDict
    from asyncio import TimeoutError as HttpTimeout
    from aiohttp import ClientSession
    
        def _extract_response_header(response)
          """
          extracts response headers from response object 
          and stores that required response header in flask.g app context
          """
          headers = CIMultiDict(response.headers)
          if 'my_response_header' not in g:
            g.my_response_header= {}
            g.my_response_header['x-custom-header'] = headers['x-custom-header']
    
    
        async def call_post_api(post_body):
          """
          sample method to make post api call using aiohttp clientsession
          """
          try:
            async with ClientSession() as session:
              async with session.post(uri, headers=_headers, json=post_body) as response:
                responseResult = await response.read()
                _extract_headers(response, responseResult)
                response_text = await response.text()
          except (HttpTimeout, ConnectionError) as ex:
            raise HttpTimeout(exception_message)
    

    file: middleware.py

    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)
            environ[self._header_name] = request_id_header
    
            def new_start_response(status, response_headers, exc_info=None):
                """
                set custom response headers
                """
                # set the request header as response header
                response_headers.append((self._header_name, request_id_header))
                # this is trying to access flask.g values set in helper class & 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)
    

    Calling the middleware from main class

    file : main.py

    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)
    
    0 讨论(0)
  • 2020-11-27 15:05

    This was how added my headers in my flask application and it worked perfectly

    @app.after_request
    def add_header(response):
        response.headers['X-Content-Type-Options'] = 'nosniff'
        return response
    
    0 讨论(0)
  • 2020-11-27 15:05

    This work for me

    from flask import Flask
    from flask import Response
    
    app = Flask(__name__)
    
    @app.route("/")
    def home():
        return Response(headers={'Access-Control-Allow-Origin':'*'})
    
    if __name__ == "__main__":
        app.run()
    
    0 讨论(0)
  • 2020-11-27 15:08

    Use make_response of Flask something like

    @app.route("/")
    def home():
        resp = make_response("hello") #here you could use make_response(render_template(...)) too
        resp.headers['Access-Control-Allow-Origin'] = '*'
        return resp
    

    From flask docs,

    flask.make_response(*args)

    Sometimes it is necessary to set additional headers in a view. Because views do not have to return response objects but can return a value that is converted into a response object by Flask itself, it becomes tricky to add headers to it. This function can be called instead of using a return and you will get a response object which you can use to attach headers.

    0 讨论(0)
提交回复
热议问题