Подтвердить что ты не робот

Javascript - заголовок No-Access-Control-Allow-Origin присутствует на запрошенном ресурсе

Мне нужно отправить данные через XmlHttpRequest с javascript на сервер python. Поскольку я использую localhost, мне нужно использовать CORS. Я использую флеш-фреймворк и его модуль 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 присутствует в запрошенном ресурс. Поэтому исходный "null" не допускается.

Как я должен это исправить? Я знаю, что мне нужно использовать заголовок "Access-Control-Allow-Origin", но я не знаю, как его реализовать в этом коде. Кстати, мне нужно использовать чистый javascript. Спасибо вам

4b9b3361

Ответ 1

Я получил Javascript, работающий с Flask, используя этот декоратор и добавив "ОПЦИИ" в список моих приемлемых методов. Декоратор должен использоваться под вашим декоратором маршрута, например:

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

Edit: Ссылка кажется нарушенной. Здесь декоратор я использовал.

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

Ответ 2

Я использовал расширение flask-cors.

Установите с помощью pip install flask-cors

Тогда это просто

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

Это позволит всем доменам

Ответ 3

Старый вопрос, но для будущих гуглеров с этой проблемой я решил (и несколько других проблем с обратным ходом, связанным с CORS) для моего приложения, поддерживающего флягу, добавив следующее в файл 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()

Ответ 4

На самом деле на сайте Flask есть яркий фрагмент, чтобы изменить заголовок сервера Access-Control-Allow-Origin. http://flask.pocoo.org/snippets/56/

У вас есть легкий путь оттуда, который позволяет каждому домену * получить доступ к вашему URL-адресу или указать ваш выбор URL-адресов внутри заголовка.

Из статьи MDN на CORS:

В этом случае сервер отвечает с помощью Access-Control-Allow-Origin: *, что означает, что доступ к ресурсу может осуществляться любым доменом на межсайтовой основе. Если владельцы ресурсов в http://bar.other хотел ограничить доступ к ресурсу только с http://foo.example, они отправили бы обратно: Access-Control-Allow-Origin: http://foo.example.

Ответ 5

При использовании 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()

При запуске на python3 или вперёд, установите фляжки с помощью команды pip install flask-cors Добавьте следующее:

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

Ответ 6

Я использовал решение от Zachary. Хорошо работает.

Для тех, кто задается вопросом, где разместить новый декоратор:

Просто скопируйте код из ссылки, предоставленной Захари, и поместите ее в файл .py

Поместите его в папку, в которой присутствуют ваши модули python (зависит от используемой вами системы и от того, используете ли вы виртуальную среду).

В своем флеш-приложении импортируйте метод crossdomain из вновь созданного модуля python и используйте его.

Ответ 7

Допустимый доступ Access-Control-Allow-Origin должен быть отправлен сервером, а не вами. Когда вы совершаете вызов в другом домене, браузер проверяет, возвращается ли этот заголовок сервером. Если это не так, вызов завершится неудачно. Я не знаю Python, поэтому я не знаю, как заставить ваш сервер отправлять этот заголовок, или даже если вы вообще можете модифицировать сервер.