Rozwiązanie Cross Origin Resource Sharing with Flask
Na następujący ajax
wniosek o Flask
(Jak mogę wykorzystać dane wysłane z ajax w flask?):
$.ajax({
url: "http://127.0.0.1:5000/foo",
type: "POST",
contentType: "application/json",
data: JSON.stringify({'inputVar': 1}),
success: function( data ) {
alert( "success" + data );
}
});
I get a Cross Origin Resource Sharing (CORS)
błąd:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'null' is therefore not allowed access.
The response had HTTP status code 500.
Próbowałem rozwiązać go na dwa następujące sposoby, ale żaden nie wydaje się działać.
- Korzystanie z kolby-CORS
Jest to rozszerzenie Flask
do obsługi CORS
, które powinno tworzyć AJAX możliwe.
- http://flask-cors.readthedocs.org/en/latest/
- Jak włączyć CORS w flask i heroku
- Flask-cors wrapper nie działa, gdy JWT auth wrapper jest stosowany.
- Javascript - brak nagłówka' Access-Control-Allow-Origin' w żądanym zasobie
Mój pythonServer.py użycie tego rozwiązania:
from flask import Flask
from flask.ext.cors import CORS, cross_origin
app = Flask(__name__)
cors = CORS(app, resources={r"/foo": {"origins": "*"}})
app.config['CORS_HEADERS'] = 'Content-Type'
@app.route('/foo', methods=['POST','OPTIONS'])
@cross_origin(origin='*',headers=['Content-Type','Authorization'])
def foo():
return request.json['inputVar']
if __name__ == '__main__':
app.run()
- korzystanie ze specjalnej kolby Dekorator
To jest oficjalny fragment kodu kolby definiujący dekorator, który powinien zezwalać CORS
na funkcje, które dekoruje.
- http://flask.pocoo.org/snippets/56/
- Python Flask cross site HTTP POST-doesn ' t work for specific allowed origins
- http://chopapp.com/#351l7gc3
Mój pythonServer.py użycie tego rozwiązania:
from flask import Flask, make_response, request, current_app
from datetime import timedelta
from functools import update_wrapper
app = Flask(__name__)
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
@app.route('/foo', methods=['GET','POST','OPTIONS'])
@crossdomain(origin="*")
def foo():
return request.json['inputVar']
if __name__ == '__main__':
app.run()
Proszę. dać jakieś wskazówki, dlaczego tak jest?
9 answers
To działało jak champ, po bitowej modyfikacji kodu
# initialization
app = Flask(__name__)
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
app.config['CORS_HEADERS'] = 'Content-Type'
cors = CORS(app, resources={r"/foo": {"origins": "http://localhost:port"}})
@app.route('/foo', methods=['POST'])
@cross_origin(origin='localhost',headers=['Content- Type','Authorization'])
def foo():
return request.json['inputVar']
if __name__ == '__main__':
app.run()
Zastąpiłem * przez localhost. Ponieważ, jak czytałem w wielu blogach i postach, powinieneś zezwolić na dostęp dla określonej domeny
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-09 18:42:59
Możesz uzyskać wyniki za pomocą prostego:
@app.route('your route', methods=['GET'])
def yourMethod(params):
response = flask.jsonify({'some': 'data'})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-12 23:27:29
Cóż, stanąłem przed tym samym problemem. Dla nowych użytkowników, którzy mogą wylądować na tej stronie. Po prostu postępuj zgodnie z ich oficjalną dokumentacją.
Install flask-cors
pip install -U flask-cors
Następnie po inicjalizacji aplikacji inicjalizuj flask-cors
z domyślnymi argumentami:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-12 16:45:57
Równie dobrze może to być odpowiedź. Miałem ten sam problem dzisiaj i to było bardziej nie-problem niż oczekiwano. Po dodaniu funkcji CORS, musisz ponownie uruchomić serwer Flask (ctrl + c
-> python manage.py runserver
, lub którąkolwiek z metod)), aby zmiana weszła w życie, nawet jeśli kod jest poprawny. W przeciwnym razie CORS nie będzie działać w aktywnej instancji.
Oto Jak to dla mnie wygląda i działa (Python 3.6.1, Flask 0.12):
Factory.py : {]}
from flask import Flask
from flask_cors import CORS # This is the magic
def create_app(register_stuffs=True):
"""Configure the app and views"""
app = Flask(__name__)
CORS(app) # This makes the CORS feature cover all routes in the app
if register_stuffs:
register_views(app)
return app
def register_views(app):
"""Setup the base routes for various features."""
from backend.apps.api.views import ApiView
ApiView.register(app, route_base="/api/v1.0/")
Views.py : {]}
from flask import jsonify
from flask_classy import FlaskView, route
class ApiView(FlaskView):
@route("/", methods=["GET"])
def index(self):
return "API v1.0"
@route("/stuff", methods=["GET", "POST"])
def news(self):
return jsonify({
"stuff": "Here be stuff"
})
W mojej konsoli aplikacji React.log:
Sending request:
GET /stuff
With parameters:
null
bundle.js:17316 Received data from Api:
{"stuff": "Here be stuff"}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-06 22:31:19
Zauważ, że ustawienie nagłówka Access-Control-Allow-Origin
w obiekcie odpowiedzi Flask jest w wielu przypadkach dobre (np. ten), ale nie ma żadnego wpływu na obsługę zasobów statycznych (przynajmniej w konfiguracji produkcyjnej). Dzieje się tak dlatego, że zasoby statyczne są obsługiwane bezpośrednio przez frontowy serwer WWW (zwykle Nginx lub Apache). W takim przypadku musisz ustawić nagłówek odpowiedzi na poziomie serwera www, a nie w Flask.
Aby uzyskać więcej szczegółów, zobacz ten artykuł, który napisałem jakiś czas temu, wyjaśniając, jak ustawić nagłówki (w moim przypadku próbowałem obsługiwać zasoby Font Awesome w różnych domenach).
Również, jak powiedział @Satu, może być konieczne zezwolenie dostępu tylko dla określonej domeny, w przypadku żądań JS AJAX. W przypadku żądania zasobów statycznych (takich jak pliki czcionek), myślę, że reguły są mniej rygorystyczne, a Zezwolenie na dostęp dla dowolnej domeny jest bardziej akceptowane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-12 05:24:10
Użyłem dekoratora podanego przez Armina Ronachera z niewielkimi modyfikacjami (z powodu różnych nagłówków, które są wymagane przez Klienta).I to mi pomogło. (gdzie używam angular jako requester requesting application / json type).
Kod jest nieco zmodyfikowany w poniższych miejscach,
from flask import jsonify
@app.route('/my_service', methods=['POST', 'GET','OPTIONS'])
@crossdomain(origin='*',headers=['access-control-allow-origin','Content-Type'])
def my_service():
return jsonify(foo='cross domain ftw')
Jsonify wyśle typ aplikacji / json, w przeciwnym razie będzie to tekst / html. nagłówki są dodawane jako klient w moim przypadku żądanie dla tych nagłówków
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin':'*'
})
};
return this.http.post<any>(url, item,httpOptions)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-02 23:21:46
Mogę się spóźnić na to pytanie, ale poniżej kroków Naprawiono problem
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-03 06:25:46
Uwaga: umieszczenie cross_origin powinno być prawidłowe i zainstalowane są zależności. Po stronie klienta, upewnij się, aby określić rodzaj serwera danych jest zużywa. Na przykład application/json lub text / html
Dla mnie kod napisany poniżej zrobił magię
from flask import Flask,request,jsonify
from flask_cors import CORS,cross_origin
app=Flask(__name__)
CORS(app, support_credentials=True)
@app.route('/api/test', methods=['POST', 'GET','OPTIONS'])
@cross_origin(supports_credentials=True)
def index():
if(request.method=='POST'):
some_json=request.get_json()
return jsonify({"key":some_json})
else:
return jsonify({"GET":"GET"})
if __name__=="__main__":
app.run(host='0.0.0.0', port=5000)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-11 11:40:25
Walczyłem z czymś podobnym. Spróbuj:
- Użyj wtyczki do przeglądarki, która może wyświetlać nagłówki HTML.
- Wprowadź adres URL do usługi i wyświetl zwrócone wartości nagłówka.
- Upewnij się, że Access-Control-Allow-Origin jest ustawione na jedną i tylko jedną domenę, która powinna być request origin. Nie ustawiaj Access-Control-Allow-Origin na *.
Jeśli to nie pomoże, spójrz na ten artykuł. Jest na PHP, ale opisuje dokładnie, które nagłówki muszą być ustawione, na które wartości mają działać CORS.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-27 08:26:25