it-swarm.com.de

So aktivieren Sie CORS in Kolben und Heroku

Ich versuche, mit Jquery eine Cross-Origin-Anfrage zu erstellen, die jedoch mit der Nachricht immer wieder abgelehnt wird 

XMLHttpRequest kann http: // ... No 'Access-Control-Allow-Origin' nicht laden Der Header befindet sich auf der angeforderten Ressource. Herkunft ... ist also Zugang nicht erlaubt.

Ich benutze eine Flasche, Heroku und Jquery 

der Client-Code sieht folgendermaßen aus:

$(document).ready(function() {
    $('#submit_contact').click(function(e){
        e.preventDefault();
        $.ajax({
            type: 'POST',
            url: 'http://...',
            // data: [
            //      { name: "name", value: $('name').val()},
            //      { name: "email", value: $('email').val() },
            //      { name: "phone", value: $('phone').val()},
            //      { name: "description", value: $('desc').val()}
            //
            // ],
            data:"name=3&email=3&phone=3&description=3",
            crossDomain:true,
            success: function(msg) {
                alert(msg);
            }
        });
    }); 
});

auf der heroku-seite benutze ich flask und es ist so

from flask import Flask,request
from flask.ext.mandrill import Mandrill
try:
    from flask.ext.cors import CORS  # The typical way to import flask-cors
except ImportError:
    # Path hack allows examples to be run without installation.
    import os
    parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    os.sys.path.insert(0, parentdir)

    from flask.ext.cors import CORS
app = Flask(__name__)

app.config['MANDRILL_API_KEY'] = '...'
app.config['MANDRILL_DEFAULT_FROM']= '...'
app.config['QOLD_SUPPORT_EMAIL']='...'
app.config['CORS_HEADERS'] = 'Content-Type'

mandrill = Mandrill(app)
cors = CORS(app)

@app.route('/email/',methods=['POST'])
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 __== '__main__':
    app.run()
26
Lopes

Hier ist das, was für mich funktioniert hat, als ich bei Heroku eingesetzt habe.

http://flask-cors.readthedocs.org/de/latest/

$ pip install -U Flaschenkapseln

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!"
59
Daniel Rasmuson

OK, ich denke nicht, dass der offizielle von Galuszkak erwähnte Snippet überall verwendet werden sollte. Wir sollten den Fall betreffen, dass während des Handlers ein Fehler aufgetreten ist, beispielsweise die hello_world-Funktion. Unabhängig davon, ob die Antwort richtig oder nicht korrekt ist, sollten wir uns den Access-Control-Allow-Origin-Header zuwenden. So ist die Sache sehr einfach, genau wie unten:

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

Das ist alles ~~

15
zhangqy

Versuchen Sie folgende Dekorateure:

@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 __== '__main__':
    app.run()

Dieser Dekorateur würde wie folgt erstellt: 

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

Sie können dieses Paket auch ausprobieren Flask-CORS

2
Newtt

Ich bin gerade mit dem gleichen Problem konfrontiert und ich kam zu der Überzeugung, dass die anderen Antworten etwas komplizierter sind, als sie sein müssen, also für diejenigen, die sich nicht auf mehr Bibliotheken oder Dekorateure verlassen wollen. Hier ist mein Ansatz:

Der Preflight

Vor der eigentlichen domänenübergreifenden POST-Anforderung gibt der Browser eine OPTIONS-Anforderung aus. Diese Antwort sollte keine Nachricht zurückgeben, sondern nur einige beruhigende Header, die dem Browser mitteilen, dass diese domänenübergreifende Anforderung bereits ausgeführt werden muss und nicht Teil eines Cross-Site-Scripting-Angriffs ist.

Ich habe eine Python-Funktion geschrieben, um diese Antwort mithilfe der make_response-Funktion aus dem flask-Modul zu erstellen.

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

Diese Antwort ist ein Platzhalter, der für alle Anforderungen geeignet ist. Wenn Sie die zusätzliche Sicherheit von CORS nutzen möchten, müssen Sie eine Whitelist mit Herkunft, Kopfzeilen und Methoden angeben.

Diese Antwort wird Ihren (Chrome) Browser davon überzeugen, die eigentliche Anfrage auszuführen.

Um die von der tatsächlichen Antwort zurückgegebenen Daten zu lesen, müssen Sie jedoch einen Header cors hinzufügen. Andernfalls blockiert der Browser sie. Beispiel mit Jsonify

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

Ich habe auch eine Funktion dafür geschrieben.

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

so können Sie einen One-Liner zurückgeben.

Schlusscode:

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
1
Niels B.

Meine Lösung ist ein Wrapper um 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.__= 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

Wenn Sie CORS für alle Routen aktivieren möchten, installieren Sie einfach flask_cors extension (pip3 install -U flask_cors) und wickeln Sie app wie folgt ein: CORS(app).

Das reicht, um es zu tun (ich habe dies mit einer POST-Anforderung zum Hochladen eines Bildes getestet, und es hat für mich funktioniert):

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

Wichtiger Hinweis: Wenn sich auf Ihrer Route ein Fehler befindet, geben Sie an, Sie versuchen, eine Variable zu drucken, die nicht vorhanden ist. Sie erhalten eine Fehlermeldung bezüglich des CORS-Fehlers, die in der Tat nichts mit CORS zu tun hat.

0