Wcześniej zapytałem, jak uzyskać dane otrzymane w żądaniu Flask, ponieważ request.data
było puste. Odpowiedź wyjaśniła, że request.data
jest to surowa treść wiadomości, ale będzie pusta, jeśli dane formularza zostaną przeanalizowane. Jak mogę bezwarunkowo otrzymać surową treść postu?
@app.route('/', methods=['POST'])
def parse_request():
data = request.data # empty in some cases
# always need raw data here, not parsed form data
request.stream
jest strumieniem nieprzetworzonych danych przekazanych do aplikacji przez serwer WSGI. Podczas czytania nie jest wykonywane żadne analizowanie, chociaż zwykle chceszrequest.get_data()
zamiast tego.Strumień będzie pusty, jeśli został wcześniej odczytany przez
request.data
lub inny atrybut.źródło
Stworzyłem oprogramowanie pośredniczące WSGI, które przechowuje surowe treści ze
environ['wsgi.input']
strumienia. Zapisałem wartość w środowisku WSGI, aby mieć do niej dostęp zrequest.environ['body_copy']
poziomu mojej aplikacji.Nie jest to konieczne w Werkzeug lub Flask, ponieważ
request.get_data()
spowoduje to pobranie surowych danych niezależnie od typu zawartości, ale z lepszą obsługą zachowania HTTP i WSGI.Powoduje to wczytanie całego ciała do pamięci, co będzie problemem, jeśli na przykład opublikowany zostanie duży plik. Nie odczyta niczego, jeśli
Content-Length
brakuje nagłówka, więc nie obsługuje żądań przesyłania strumieniowego.from io import BytesIO class WSGICopyBody(object): def __init__(self, application): self.application = application def __call__(self, environ, start_response): length = int(environ.get('CONTENT_LENGTH') or 0) body = environ['wsgi.input'].read(length) environ['body_copy'] = body # replace the stream since it was exhausted by read() environ['wsgi.input'] = BytesIO(body) return self.application(environ, start_response) app.wsgi_app = WSGICopyBody(app.wsgi_app)
request.environ['body_copy']
źródło
request.data
będzie pusty, jeślirequest.headers["Content-Type"]
zostanie rozpoznany jako dane formularza, do którego zostaną przetworzonerequest.form
. Aby uzyskać nieprzetworzone dane niezależnie od typu zawartości, użyjrequest.get_data()
.request.data
wywołańrequest.get_data(parse_form_data=True)
, co powoduje różne zachowanie danych formularza.źródło