Para la siguiente ajax
solicitud de publicación para Flask
( ¿cómo puedo usar los datos publicados desde ajax en el matraz? ):
$.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 );
}
});
Me sale un Cross Origin Resource Sharing (CORS)
error:
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.
Intenté resolverlo de las dos formas siguientes, pero ninguna parece funcionar.
- Usando Flask-CORS
Esta es una Flask
extensión para el manejo CORS
que debería hacer posible AJAX de origen cruzado.
- http://flask-cors.readthedocs.org/en/latest/
- Cómo habilitar CORS en flask y heroku
- El contenedor Flask-cors no funciona cuando se aplica el contenedor de autenticación jwt.
- Javascript: no hay un encabezado 'Access-Control-Allow-Origin' presente en el recurso solicitado
Mi pythonServer.py usando esta solución:
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 __name__ == '__main__':
app.run()
- Uso de un decorador de matraces específico
Este es un fragmento de código oficial de Flask que define un decorador que debe permitir CORS
las funciones que decora.
- http://flask.pocoo.org/snippets/56/
- Python Flask cross site HTTP POST: no funciona para orígenes permitidos específicos
- http://chopapp.com/#351l7gc3
Mi pythonServer.py usando esta solución:
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 __name__ == '__main__':
app.run()
¿Puede dar alguna indicación de por qué es así?