Fix Python – How do I set response headers in Flask?


Asked By – dopatraman

This is my code:

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

However, when I make a request from the browser to my server I get this error:

XMLHttpRequest cannot load http://localhost:5000/hello. 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have also tried this approach, setting the response headers “after” the request:

def add_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response

No dice. I get the same error. Is there a way to just set the response headers in the route function? Something like this would be ideal:

@app.route('/hello', methods=["POST"])
    def hello(response): # is this a thing??
        response.headers['Access-Control-Allow-Origin'] = '*'
        return response

but I cant find anyway to do this. Please help.


if I curl the url with a POST request like so:

curl -iX POST http://localhost:5000/hello

I get this response:

Content-Type: text/html
Content-Length: 291
Server: Werkzeug/0.9.6 Python/2.7.6
Date: Tue, 16 Sep 2014 03:58:42 GMT

<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request.  Either the server is overloaded or there is an error in the application.</p>

Any ideas?

Now we will see solution for issue: How do I set response headers in Flask?


You can do this pretty easily:

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.

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

You should see

> curl -i ''
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.

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:

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/", line 8, in home
    user.weapon = boomerang
NameError: global name 'boomerang' is not defined

This question is answered By – sberry

This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0