Pour la demande suivante ajax
post pour Flask
( comment puis-je utiliser les données postées depuis ajax dans une fiole? ):
$.ajax({
url: "http://127.0.0.1:5000/foo",
type: "POST",
contentType: "application/json",
data: JSON.stringify({'inputVar': 1}),
success: function( data ) {
alert( "success" + data );
}
});
Je reçois un Cross Origin Resource Sharing (CORS)
erreur:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'null' is therefore not allowed access.
The response had HTTP status code 500.
J'ai essayé de le résoudre de deux manières, mais aucune ne semble fonctionner.
Il s’agit d’une extension Flask
pour la gestion de CORS
qui devrait permettre l’origine croisée AJAX).
Mon pythonServer.py en utilisant cette solution:
from flask import Flask
from flask.ext.cors import CORS, cross_Origin
app = Flask(__name__)
cors = CORS(app, resources={r"/foo": {"origins": "*"}})
app.config['CORS_HEADERS'] = 'Content-Type'
@app.route('/foo', methods=['POST','OPTIONS'])
@cross_Origin(origin='*',headers=['Content-Type','Authorization'])
def foo():
return request.json['inputVar']
if __== '__main__':
app.run()
Ceci est un extrait de code officiel Flask) définissant un décorateur devant autoriser CORS
sur les fonctions qu’il décore.
Mon pythonServer.py en utilisant cette solution:
from flask import Flask, make_response, request, current_app
from datetime import timedelta
from functools import update_wrapper
app = Flask(__name__)
def crossdomain(Origin=None, methods=None, headers=None,
max_age=21600, attach_to_all=True,
automatic_options=True):
if methods is not None:
methods = ', '.join(sorted(x.upper() for x in methods))
if headers is not None and not isinstance(headers, basestring):
headers = ', '.join(x.upper() for x in headers)
if not isinstance(Origin, basestring):
Origin = ', '.join(Origin)
if isinstance(max_age, timedelta):
max_age = max_age.total_seconds()
def get_methods():
if methods is not None:
return methods
options_resp = current_app.make_default_options_response()
return options_resp.headers['allow']
def decorator(f):
def wrapped_function(*args, **kwargs):
if automatic_options and request.method == 'OPTIONS':
resp = current_app.make_default_options_response()
else:
resp = make_response(f(*args, **kwargs))
if not attach_to_all and request.method != 'OPTIONS':
return resp
h = resp.headers
h['Access-Control-Allow-Origin'] = Origin
h['Access-Control-Allow-Methods'] = get_methods()
h['Access-Control-Max-Age'] = str(max_age)
if headers is not None:
h['Access-Control-Allow-Headers'] = headers
return resp
f.provide_automatic_options = False
return update_wrapper(wrapped_function, f)
return decorator
@app.route('/foo', methods=['GET','POST','OPTIONS'])
@crossdomain(Origin="*")
def foo():
return request.json['inputVar']
if __== '__main__':
app.run()
Pouvez-vous s'il vous plaît donner quelques indications sur la raison?
Cela a fonctionné comme un champion, après modification mineure de votre code
# initialization
app = Flask(__name__)
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
app.config['CORS_HEADERS'] = 'Content-Type'
cors = CORS(app, resources={r"/foo": {"origins": "http://localhost:port"}})
@app.route('/foo', methods=['POST'])
@cross_Origin(origin='localhost',headers=['Content- Type','Authorization'])
def foo():
return request.json['inputVar']
if __== '__main__':
app.run()
J'ai remplacé * par localhost. Comme je l'ai lu dans de nombreux blogs et publications, vous devez autoriser l'accès à un domaine spécifique.
Vous pouvez obtenir les résultats avec un simple:
@app.route('your route', methods=['GET'])
def yourMethod(params):
response = flask.jsonify({'some': 'data'})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
Eh bien, j'ai fait face au même problème. Pour les nouveaux utilisateurs qui peuvent atterrir sur cette page. Il suffit de suivre leur documentation officielle.
Installer des flacons
pip install -U flask-cors
puis après l'initialisation de l'application, initialisez flask-cors
avec arguments par défaut:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello, cross-Origin-world!"
Notez que le réglage de la Access-Control-Allow-Origin
en-tête dans l'objet réponse Flask) convient dans de nombreux cas (comme celui-ci), mais cela n'a aucun effet lors de la gestion d'actifs statiques (dans une configuration de production, du moins). Les ressources statiques sont gérées directement par le serveur Web frontal (généralement Nginx ou Apache). Dans ce cas, vous devez définir l'en-tête de la réponse au niveau du serveur Web et non dans Flask.
Pour plus de détails, voir cet article que j'ai écrit il y a quelque temps, expliquant comment définir les en-têtes (dans mon cas, j'essayais de servir la distribution inter-domaines d'actifs Font Awesome).
En outre, comme @Satu l'a dit, vous devrez peut-être autoriser l'accès uniquement à un domaine spécifique, dans le cas de demandes JS AJAX. Pour les demandes d'actifs statiques (comme les fichiers de polices), je pense que les règles sont moins strictes, et permettre l’accès à n’importe quel domaine est plus accepté.
Autant en faire une réponse. J'ai eu le même problème aujourd'hui et c'était plus un non-problème que prévu. Après avoir ajouté la fonctionnalité CORS, vous devez redémarrer votre Flask serveur (ctrl + c
-> python manage.py runserver
, ou quelle que soit la méthode utilisée))) pour que la modification soit prise en compte, même si le code est correct. Sinon, le CORS ne fonctionnera pas dans l'instance active.
Voici à quoi ça ressemble pour moi et cela fonctionne (Python 3.6.1, Flask 0.12):
factory.py :
from flask import Flask
from flask_cors import CORS # This is the magic
def create_app(register_stuffs=True):
"""Configure the app and views"""
app = Flask(__name__)
CORS(app) # This makes the CORS feature cover all routes in the app
if register_stuffs:
register_views(app)
return app
def register_views(app):
"""Setup the base routes for various features."""
from backend.apps.api.views import ApiView
ApiView.register(app, route_base="/api/v1.0/")
views.py :
from flask import jsonify
from flask_classy import FlaskView, route
class ApiView(FlaskView):
@route("/", methods=["GET"])
def index(self):
return "API v1.0"
@route("/stuff", methods=["GET", "POST"])
def news(self):
return jsonify({
"stuff": "Here be stuff"
})
Dans mon React app console.log:
Sending request:
GET /stuff
With parameters:
null
bundle.js:17316 Received data from Api:
{"stuff": "Here be stuff"}
J'ai utilisé décorateur donné par Armin Ronacher avec peu de modifications (en raison des en-têtes différents demandés par le client). Et cela a fonctionné pour moi. (où j'utilise angular comme demandeur demandant le type d'application/json).
Le code est légèrement modifié aux endroits ci-dessous,
from flask import jsonify
@app.route('/my_service', methods=['POST', 'GET','OPTIONS'])
@crossdomain(Origin='*',headers=['access-control-allow-Origin','Content-Type'])
def my_service():
return jsonify(foo='cross domain ftw')
jsonify enverra un type application/json, sinon ce sera text/html. les en-têtes sont ajoutés en tant que client dans ma demande de cas pour ces en-têtes
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin':'*'
})
};
return this.http.post<any>(url, item,httpOptions)
Remarque: L'emplacement de cross_Origin doit être correct et les dépendances sont installées. Du côté du client, assurez-vous de spécifier le type de consommation du serveur de données. Par exemple application/json ou text/html
Pour moi, le code écrit ci-dessous était magique
from flask import Flask,request,jsonify
from flask_cors import CORS,cross_Origin
app=Flask(__name__)
CORS(app, support_credentials=True)
@app.route('/api/test', methods=['POST', 'GET','OPTIONS'])
@cross_Origin(supports_credentials=True)
def index():
if(request.method=='POST'):
some_json=request.get_json()
return jsonify({"key":some_json})
else:
return jsonify({"GET":"GET"})
if __name__=="__main__":
app.run(Host='0.0.0.0', port=5000)
J'ai beaucoup lutté avec quelque chose de similaire. Essayez ce qui suit:
Si cela ne vous aide pas, jetez un oeil à cet article. C'est sur PHP, mais il décrit exactement quels en-têtes doivent être définis sur quelles valeurs pour que CORS fonctionne.