restful javascript python ajax flask cors

javascript - flask restful cors



Javascript-No hay encabezado ''Access-Control-Allow-Origin'' presente en el recurso solicitado (7)

Al usar Python 2.7

app = Flask(__name__) api = Api(app) @app.after_request def after_request(response): response.headers.add(''Access-Control-Allow-Origin'', ''*'') response.headers.add(''Access-Control-Allow-Headers'', ''Content-Type,Authorization'') response.headers.add(''Access-Control-Allow-Methods'', ''GET,PUT,POST,DELETE,OPTIONS'') return response if __name__ == ''__main__'': app.run()

Cuando se ejecuta en python3 o adelante, instale flask-cors usando el comando pip install flask-cors Agregue lo siguiente:

from flask_cors import CORS app = Flask(__name__) CORS(app)

Necesito enviar datos a través de XmlHttpRequest desde javascript a python server. Como uso localhost, necesito usar CORS. Estoy usando el marco Flask y su módulo flask_cors. Como javascript, tengo esto:

var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("POST", "http://localhost:5000/signin", true); var params = "email=" + email + "&password=" + password; xmlhttp.onreadystatechange = function() {//Call a function when the state changes. if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { alert(xmlhttp.responseText); } } xmlhttp.send(params);

y código python:

@app.route(''/signin'', methods=[''POST'']) @cross_origin() def sign_in(): email = cgi.escape(request.values["email"]) password = cgi.escape(request.values["password"])

pero cuando lo ejecuto recibo este mensaje:

XMLHttpRequest no puede cargar localhost: 5000 / signin. Ningún encabezado ''Access-Control-Allow-Origin'' está presente en el recurso solicitado. Por lo tanto, el origen ''nulo'' no está permitido.

¿Cómo debería arreglarlo? Sé que necesito usar un encabezado "Access-Control-Allow-Origin" pero no sé cómo implementarlo en este código. Por cierto, necesito usar javascript puro.


En realidad, hay un fragmento brillante en el sitio de Flask para modificar el encabezado del servidor del encabezado Access-Control-Allow-Origin . here

Tiene la salida fácil desde allí, que es permitir que cada * dominio acceda a su URL, o especificar su selección de URL dentro del encabezado.

Del artículo de MDN sobre CORS :

En este caso, el servidor responde con un Access-Control-Allow-Origin: * que significa que se puede acceder al recurso desde cualquier dominio de forma cruzada. Si los propietarios de los recursos en http: //bar.other deseaban restringir el acceso al recurso solo desde http: //foo.example , enviarían de vuelta: Access-Control-Allow-Origin: http://foo.example .


He usado la extensión de matraz-cors .

Instalar usando pip install flask-cors

Entonces es simplemente

from flask_cors import CORS app = Flask(__name__) CORS(app)

Esto permitirá todos los dominios


He usado la solución de Zachary. Funciona bien.

Para aquellos que se preguntan dónde colocar el nuevo decorador:

Solo copie el código del enlace que Zachary proporcionó y colóquelo en un archivo .py

Colóquelo en la carpeta donde están sus módulos de python (varía según el sistema que use y si está utilizando un entorno virtual o no).

En su aplicación de matraz, importe el método crossdomain desde el módulo de python recién creado y crossdomain .


Obtuve Javascript trabajando con Flask al usar este decorator y agregando "OPCIONES" a mi lista de métodos aceptables. El decorador debe usarse debajo del decorador de tu ruta, así:

@app.route(''/login'', methods=[''POST'', ''OPTIONS'']) @crossdomain(origin=''*'') def login() ...

Editar: el enlace parece estar roto. Aquí está el decorador que utilicé.

def crossdomain(origin=None, methods=None, headers=None, max_age=21600, attach_to_all=True, automatic_options=True): """Decorator function that allows crossdomain requests. Courtesy of https://blog.skyred.fi/articles/better-crossdomain-snippet-for-flask.html """ 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(): """ Determines which methods are allowed """ if methods is not None: return methods options_resp = current_app.make_default_options_response() return options_resp.headers[''allow''] def decorator(f): """The decorator function """ def wrapped_function(*args, **kwargs): """Caries out the actual cross domain code """ 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) h[''Access-Control-Allow-Credentials''] = ''true'' h[''Access-Control-Allow-Headers''] = / "Origin, X-Requested-With, Content-Type, Accept, Authorization" 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


Una vieja pregunta, pero para futuros usuarios de Google con este problema, lo resolví (y algunos otros problemas de flujo descendente relacionados con CORS) para mi aplicación de repositorio de frasco agregando lo siguiente a mi archivo app.py:

app = Flask(__name__) api = Api(app) @app.after_request def after_request(response): response.headers.add(''Access-Control-Allow-Origin'', ''*'') response.headers.add(''Access-Control-Allow-Headers'', ''Content-Type,Authorization'') response.headers.add(''Access-Control-Allow-Methods'', ''GET,PUT,POST,DELETE,OPTIONS'') return response if __name__ == ''__main__'': app.run()


Access-Control-Allow-Origin debe ser enviado por el servidor, no por usted. Cuando realiza una llamada a otro dominio, el navegador verifica si el servidor devuelve este encabezado. Si no es así, la llamada falla. No conozco Python, así que no sé cómo hacer que tu servidor envíe este encabezado, o incluso si puedes modificar el servidor.