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í?
Respuestas:
Funcionó como un campeón, después de una pequeña modificación en su código
# 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 __name__ == '__main__': app.run()
Reemplacé * por localhost. Como leo en muchos blogs y publicaciones, debe permitir el acceso para un dominio específico
fuente
Puede obtener los resultados con 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
fuente
yourMethod
es:return render_template('template.html',some_var = response)
Bueno, me enfrenté al mismo problema. Para nuevos usuarios que puedan aterrizar en esta página. Simplemente siga su documentación oficial.
Instalar flask-cors
pip install -U flask-cors
luego, después de la inicialización de la aplicación, inicialice
flask-cors
con los argumentos predeterminados:from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app) @app.route("/") def helloWorld(): return "Hello, cross-origin-world!"
fuente
Access-Control-Max-Age
paraflask_cors
?Bien podría hacer de esto una respuesta. Tuve el mismo problema hoy y no fue un problema más de lo esperado. Después de agregar la funcionalidad CORS, debe reiniciar su servidor Flask (
ctrl + c
->python manage.py runserver
, o cualquier método que use)) para que el cambio surta efecto, incluso si el código es correcto. De lo contrario, CORS no funcionará en la instancia activa.Así es como se ve para mí y funciona (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" })
En mi aplicación de React console.log:
Sending request: GET /stuff With parameters: null bundle.js:17316 Received data from Api: {"stuff": "Here be stuff"}
fuente
Tenga en cuenta que configurar el
Access-Control-Allow-Origin
encabezado en el objeto de respuesta Flask está bien en muchos casos (como este), pero no tiene ningún efecto cuando se sirven activos estáticos (en una configuración de producción, al menos). Eso es porque los activos estáticos son servidos directamente por el servidor web frontal (generalmente Nginx o Apache). Entonces, en ese caso, debe configurar el encabezado de respuesta en el nivel del servidor web, no en Flask.Para obtener más detalles, consulte este artículo que escribí hace un tiempo, que explica cómo configurar los encabezados (en mi caso, estaba tratando de hacer un servicio entre dominios de los activos de Font Awesome).
Además, como dijo @Satu, es posible que deba permitir el acceso solo para un dominio específico, en el caso de las solicitudes JS AJAX. Para solicitar activos estáticos (como archivos de fuentes), creo que las reglas son menos estrictas y se acepta más el acceso a cualquier dominio.
fuente
Solía decorador dada por Armin Ronacher con pequeñas modificaciones (debido a las diferentes cabeceras que son solicitados por el cliente) .Y que trabajó para mí. (donde uso angular como solicitante que solicita el tipo de aplicación / json).
El código se modifica ligeramente en los lugares siguientes,
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 enviará un tipo application / json, de lo contrario será text / html. los encabezados se agregan como el cliente en mi solicitud de caso para esos encabezados
const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', 'Access-Control-Allow-Origin':'*' }) }; return this.http.post<any>(url, item,httpOptions)
fuente
Nota: La ubicación de cross_origin debe ser correcta y las dependencias están instaladas. En el lado del cliente, asegúrese de especificar el tipo de servidor de datos que consume. Por ejemplo, application / json o text / html
Para mí, el código escrito a continuación hizo magia.
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)
fuente
cross_origin
?Luché mucho con algo similar. Intente lo siguiente:
Si esto no ayuda, eche un vistazo a este artículo. Está en PHP, pero describe exactamente qué encabezados deben establecerse en qué valores para que CORS funcione.
CORS que funciona en IE, Firefox, Chrome y Safari
fuente
Puede que llegue tarde en esta pregunta, pero los pasos siguientes solucionaron el problema
from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app)
fuente