[python] Content-Type 헤더에 관계없이 Python Flask에서 원시 POST 본문 가져 오기
이전에는 비어 있기 때문에 플라스크 요청에서 데이터를받는 방법을 물었 request.data
습니다. 대답 request.data
은 원시 게시물 본문이지만 양식 데이터를 구문 분석하면 비워집니다. 원시 포스트 바디를 무조건 얻을 수있는 방법은 무엇입니까?
@app.route('/', methods=['POST'])
def parse_request():
data = request.data # empty in some cases
# always need raw data here, not parsed form data
답변
request.get_data()
컨텐츠 유형에 관계없이 원시 데이터를 가져 오는 데 사용하십시오 . 데이터는 캐시되며 이후 액세스 할 수있는 request.data
, request.json
, request.form
의지.
당신이 액세스하는 경우 request.data
첫째, 그것은 호출 get_data
첫 번째 양식 데이터를 구문 분석하는 인수와 함께. 요청 폼 콘텐츠 타입이있는 경우 ( multipart/form-data
, application/x-www-form-urlencoded
나 application/x-url-encoded
)는 원시 데이터가 소모 될 것이다. request.data
그리고 request.json
이 경우 빈 나타납니다.
답변
request.stream
WSGI 서버가 애플리케이션에 전달한 원시 데이터 스트림입니다. 읽을 때는 일반적으로 구문 분석이 수행되지 않습니다 request.get_data()
.
data = request.stream.read()
이전에 읽은 스트림 request.data
또는 다른 속성 인 경우 스트림이 비어 있습니다 .
답변
environ['wsgi.input']
스트림 에서 원시 본문을 저장하는 WSGI 미들웨어를 작성했습니다 . WSGI 환경에 값을 저장하여 request.environ['body_copy']
앱 내 에서 액세스 할 수 있습니다 .
request.get_data()
컨텐츠 유형에 관계없이 원시 데이터를 가져 오지만 HTTP 및 WSGI 동작을보다 잘 처리 하므로 Werkzeug 또는 Flask에서는 필요하지 않습니다 .
이것은 전체 본문을 메모리로 읽습니다. 예를 들어 큰 파일이 게시되면 문제가됩니다. Content-Length
헤더가 없으면 아무것도 읽지 않으므로 스트리밍 요청을 처리하지 않습니다.
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']
답변
request.data
request.headers["Content-Type"]
양식 데이터로 인식 되면로 비워 지며로 분석됩니다 request.form
. 컨텐츠 유형에 관계없이 원시 데이터를 얻으려면을 사용하십시오 request.get_data()
.
request.data
전화 request.get_data(parse_form_data=True)
, 폼 데이터에 대한 다른 행동의 결과.