我需要通过XmlHttpRequestJavaScript 将数据发送到Python服务器。因为我使用的是localhost,所以我需要使用CORS。我正在使用Flask框架及其模块flask_cors。
XmlHttpRequest
flask_cors
作为JavaScript,我有这个:
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);
和Python代码:
@app.route('/signin', methods=['POST']) @cross_origin() def sign_in(): email = cgi.escape(request.values["email"]) password = cgi.escape(request.values["password"])
但是当我执行它时,我收到以下消息:
XMLHttpRequest无法加载localhost:5000 / signin。所请求的资源上没有“ Access-Control-Allow- Origin”标头。因此,不允许访问原始“空”。
我该如何解决?我知道我需要使用一些“ Access-Control-Allow- Origin”标头,但我不知道如何在此代码中实现它。顺便说一句,我需要使用纯JavaScript。
通过使用此装饰器,我将Javascript与Flask配合使用,并在可接受的方法列表中添加了“ OPTIONS”。装饰器应在路线装饰器下方使用,如下所示:
@app.route('/login', methods=['POST', 'OPTIONS']) @crossdomain(origin='*') def login() ...
编辑: 链接似乎已断开。这是我使用的装饰器。
from datetime import timedelta from flask import make_response, request, current_app from functools import update_wrapper 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)) # use str instead of basestring if using Python 3.x if headers is not None and not isinstance(headers, basestring): headers = ', '.join(x.upper() for x in headers) # use str instead of basestring if using Python 3.x 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