Я думаю, вы могли бы проверить пример на aiohttp документе о сервере загрузки файлов .Но этот фрагмент неоднозначен, и документ не очень хорошо объясняет себя.
Поработав некоторое время над его исходным кодом, я обнаружил, что request.multipart()
на самом деле дает экземпляр MultipartReader
, который обрабатывает multipart/form-data
запросов по одному полю каждый раз при вызове .next()
, давая другое BodyPartReader
instance.
В вашем неработающем коде image = await reader.next()
эта строка фактически считывает одно целое поле из данных формы, и вы не можете быть уверены, какое это поле на самом деле.Это может быть поле token
, поле key
, поле filename
, поле aaa
... или любое из них.Таким образом, в вашем неработающем примере эта функция сопрограммы post_image
будет обрабатывать только одно поле из запрашиваемых вами данных, и вы не можете быть уверены, что это поле aaa
file.
Вот мой фрагмент кода,
async def post_image(self, request):
# Iterate through each field of MultipartReader
async for field in (await request.multipart()):
if field.name == 'token':
# Do something about token
token = (await field.read()).decode()
pass
if field.name == 'key':
# Do something about key
pass
if field.name == 'filename':
# Do something about filename
pass
if field.name == 'aaa':
# Process any files you uploaded
filename = field.filename
# In your example, filename should be "2C80...jpg"
# Deal with actual file data
size = 0
with open(os.path.join('', filename), 'wb') as fd:
while True:
chunk = await field.read_chunk()
if not chunk:
break
size += len(chunk)
fd.write(chunk)
# Reply ok, all fields processed successfully
return await self.reply_ok([])
И приведенный выше фрагмент также может работать с несколькими файлами в одном запросе с повторяющимся именем поля, или 'aaa' в вашем примере.Заголовок filename
in Content-Disposition
должен автоматически заполняться самим браузером, поэтому не нужно беспокоиться о filename
.
Кстати, при работе с загрузками файлов в запросах data = await request.post()
будет съедатьзначительное количество памяти для загрузки файловых данных.Поэтому при загрузке файлов следует избегать request.post()
, вместо этого используйте request.multipart()
.