web-dev-qa-db-fra.com

Comment définir les en-têtes de réponse dans Flask?

Ceci est mon code:

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

Cependant, lorsque je fais une demande du navigateur à mon serveur, j'obtiens cette erreur:

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

J'ai également essayé cette approche en définissant les en-têtes de réponse "après" la requête:

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

Pas de dé. J'ai la même erreur. Est-il possible de définir simplement les en-têtes de réponse dans la fonction route? Quelque chose comme ça serait l'idéal:

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

mais je ne trouve pas quand même faire cela. S'il vous plaît aider.

EDIT

si je boucle l'URL avec une demande POST comme ceci:

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

Je reçois cette réponse:

HTTP/1.0 500 INTERNAL SERVER ERROR
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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<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>

Des idées?

78
dopatraman

Vous pouvez le faire assez facilement:

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

Regardez flask.Response et flask.make_response ()

Mais quelque chose me dit que vous avez un autre problème, parce que le after_request aurait dû le gérer correctement aussi.

EDIT
Je viens de remarquer que vous utilisez déjà make_response, qui est l’un des moyens de le faire. Comme je l'ai déjà dit, after_request aurait également dû fonctionner. Essayez de frapper le point final via curl et voyez ce que sont les en-têtes:

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

Tu devrais voir

> 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

Notant l'en-tête Access-Control-Allow-Origin.

EDIT 2
Comme je le soupçonnais, vous obtenez un 500 et vous ne définissez pas l'en-tête comme vous le pensiez. Essayez d’ajouter app.debug = True avant de lancer l’application, puis réessayez. Vous devriez obtenir une sortie indiquant la cause première du problème.

Par exemple:

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

Donne une page d'erreur HTML bien formatée, avec ceci en bas (utile pour la commande curl)

Traceback (most recent call last):
...
  File "/private/tmp/min.py", line 8, in home
    user.weapon = boomerang
NameError: global name 'boomerang' is not defined
74
sberry

Utilisez make_response sur Flask quelque chose comme

@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

De flask docs ,

flask.make_response (* arguments)

Il est parfois nécessaire de définir des en-têtes supplémentaires dans une vue. Etant donné que les vues ne doivent pas nécessairement renvoyer les objets de réponse mais peuvent renvoyer une valeur convertie en objet de réponse par Flask elle-même, il devient délicat de lui ajouter des en-têtes. Cette fonction peut être appelée au lieu d'utiliser un retour et vous obtiendrez un objet de réponse que vous pourrez utiliser pour attacher des en-têtes.

15
Devi

Ce travail pour moi

from flask import Flask
from flask import Response

app = Flask(__name__)

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

if __== "__main__":
    app.run()
3
German Lopez