Как включить CORS в колбу и героку

Не нужно определять пользовательскую функцию, вместо этого мы можем просто суммировать все элементы группы, вычесть текущее значение и делить на число элементов на группу минус 1.

df %>% group_by(grouping) %>%
        mutate(special_mean = (sum(value) - value)/(n()-1))
#   grouping value special_mean
#      (chr) (int)        (dbl)
#1         A     1          8.5
#2         A     6          6.0
#3         A    11          3.5
#4         B     2          9.5
#5         B     7          7.0
29
задан Lopes 31 August 2014 в 18:15
поделиться

6 ответов

Хорошо, я не думаю, что официальный фрагмент, упомянутый galuszkak, должен использоваться везде, мы должны рассмотреть случай, когда некоторая ошибка может быть вызвана во время обработчика, такого как функция hello_world. Независимо от того, является ли ответ правильным или неправильным, мы должны обратить внимание на заголовок Access-Control-Allow-Origin. Итак, все очень просто, как показано ниже:

@blueprint.after_request # blueprint can also be app~~
def after_request(response):
    header = response.headers
    header['Access-Control-Allow-Origin'] = '*'
    return response

Это все ~~

22
ответ дан zhangqy 31 August 2014 в 18:15
поделиться

Я только что столкнулся с той же проблемой и пришел к выводу, что другие ответы немного сложнее, чем они должны быть, поэтому вот мой подход для тех, кто не хочет полагаться на большее количество библиотек или декораторов:

Запрос CORS фактически состоит из двух HTTP-запросов. Запрос предварительной проверки, а затем фактический запрос, который выполняется только в случае успешной предварительной проверки.

Предварительный запрос

Перед фактическим междоменным запросом POST браузер отправит запрос OPTIONS. Этот ответ не должен возвращать никакого тела, а только некоторые обнадеживающие заголовки, сообщающие браузеру, что можно делать этот междоменный запрос и что он не является частью какой-либо атаки межсайтового скриптинга.

Я написал функцию Python для построения этого ответа, используя функцию make_response из модуля flask.

def _build_cors_prelight_response():
    response = make_response()
    response.headers.add("Access-Control-Allow-Origin", "*")
    response.headers.add("Access-Control-Allow-Headers", "*")
    response.headers.add("Access-Control-Allow-Methods", "*")
    return response

Этот ответ является символом подстановки, который работает для всех запросов. Если вы хотите получить дополнительную безопасность, обеспечиваемую CORS, вы должны предоставить белый список источников, заголовков и методов.

Этот ответ убедит ваш браузер (Chrome) идти вперед и выполнить фактический запрос.

Фактический запрос

При обслуживании фактического запроса вы должны добавить один заголовок CORS - в противном случае браузер не вернет ответ на вызывающий код JavaScript. Вместо этого запрос потерпит неудачу на стороне клиента. Пример с jsonify

response = jsonify({"order_id": 123, "status": "shipped"}
response.headers.add("Access-Control-Allow-Origin", "*")
return response

Я также написал функцию для этого.

def _corsify_actual_response(response):
    response.headers.add("Access-Control-Allow-Origin", "*")
    return response

позволяя вам вернуть однострочник.

Окончательный код

from flask import Flask, request, jsonify, make_response
from models import OrderModel

flask_app = Flask(__name__)

@flask_app.route("/api/orders", methods=["POST", "OPTIONS"])
def api_create_order():
    if request.method == "OPTIONS": # CORS preflight
        return _build_cors_prelight_response()
    elif request.method == "POST": # The actual request following the preflight
        order = OrderModel.create(...) # Whatever.
        return _corsify_actual_response(jsonify(order.to_dict()))
    else
        raise RuntimeError("Wierd - don't know how to handle method {}".format(request.method))

def _build_cors_prelight_response():
    response = make_response()
    response.headers.add("Access-Control-Allow-Origin", "*")
    response.headers.add('Access-Control-Allow-Headers', "*")
    response.headers.add('Access-Control-Allow-Methods', "*")
    return response

def _corsify_actual_response(response):
    response.headers.add("Access-Control-Allow-Origin", "*")
    return response
4
ответ дан Niels B. 31 August 2014 в 18:15
поделиться

Вот что сработало для меня, когда я развернулся в Heroku.

http://flask-cors.readthedocs.org/en/latest/
Установите колбу, запустив - pip install -U flask-cors

from flask import Flask
from flask_cors import CORS, cross_origin
app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'

@app.route("/")
@cross_origin()
def helloWorld():
  return "Hello, cross-origin-world!"
65
ответ дан abc 31 August 2014 в 18:15
поделиться

Попробуйте следующие декораторы:

@app.route('/email/',methods=['POST', 'OPTIONS']) #Added 'Options'
@crossdomain(origin='*')                          #Added
def hello_world():
    name=request.form['name']
    email=request.form['email']
    phone=request.form['phone']
    description=request.form['description']

    mandrill.send_email(
        from_email=email,
        from_name=name,
        to=[{'email': app.config['QOLD_SUPPORT_EMAIL']}],
        text="Phone="+phone+"\n\n"+description
    )

    return '200 OK'

if __name__ == '__main__':
    app.run()

Этот декоратор будет создан следующим образом:

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):

    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

Вы также можете проверить этот пакет Flask-CORS

3
ответ дан galuszkak 31 August 2014 в 18:15
поделиться

Если вы хотите включить CORS для всех маршрутов, просто установите расширение flask_cors (pip3 install -U flask_cors) и оберните app следующим образом: CORS(app).

Этого достаточно, чтобы сделать это (я проверил это с помощью POST запроса на загрузку изображения, и это сработало для меня):

from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # This will enable CORS for all routes

Важное примечание: если в вашем приложении есть ошибка Например, если вы попытаетесь напечатать несуществующую переменную, вы получите сообщение об ошибке CORS, которое на самом деле не имеет ничего общего с CORS.

3
ответ дан Billal Begueradj 31 August 2014 в 18:15
поделиться

Мое решение - обертка вокруг app.route:

def corsapp_route(path, origin=('127.0.0.1',), **options):
    """
    Flask app alias with cors
    :return:
    """

    def inner(func):
        def wrapper(*args, **kwargs):
            if request.method == 'OPTIONS':
                response = make_response()
                response.headers.add("Access-Control-Allow-Origin", ', '.join(origin))
                response.headers.add('Access-Control-Allow-Headers', ', '.join(origin))
                response.headers.add('Access-Control-Allow-Methods', ', '.join(origin))
                return response
            else:
                result = func(*args, **kwargs)
            if 'Access-Control-Allow-Origin' not in result.headers:
                result.headers.add("Access-Control-Allow-Origin", ', '.join(origin))
            return result

        wrapper.__name__ = func.__name__

        if 'methods' in options:
            if 'OPTIONS' in options['methods']:
                return app.route(path, **options)(wrapper)
            else:
                options['methods'].append('OPTIONS')
                return app.route(path, **options)(wrapper)

        return wrapper

    return inner

@corsapp_route('/', methods=['POST'], origin=['*'])
def hello_world():
    ...
0
ответ дан yurzs 31 August 2014 в 18:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: