![](/img/trans.png)
[英]The aiohttp GET request returns nothing, as if the console is frozen
[英]aiohttp request.multipart() get nothing from browser uploading files
浏览器使用vue element-ui el-upload组件上传文件,并且aiohttp作为后端接收表单数据然后保存。aiohttp request.multipart()始终为空,但request.post()可以。
提示:
<el-upload class="image-uploader"
:data="dataObj"
drag
name="aaa"
:multiple="false"
:show-file-list="false"
:action="action" -> upload url,passed from outer component
:on-success="handleImageScucess">
<i class="el-icon-upload"></i>
</el-upload>
export default {
name: 'singleImageUpload3',
props: {
value: String,
action: String
},
methods: {
handleImageScucess(file) {
this.emitInput(file.files.file)
},
}
aiohttp:不起作用
async def post_image(self, request):
reader = await request.multipart()
image = await reader.next()
print (image.text())
filename = image.filename
print (filename)
size = 0
with open(os.path.join('', 'aaa.jpg'), 'wb') as f:
while True:
chunk = await image.read_chunk()
print ("chunk", chunk)
if not chunk:
break
size += len(chunk)
f.write(chunk)
return await self.reply_ok([])
aiohttp:工作
async def post_image(self, request):
data = await request.post()
print (data)
mp3 = data['aaa']
filename = mp3.filename
mp3_file = data['aaa'].file
content = mp3_file.read()
with open('aaa.jpg', 'wb') as f:
f.write(content)
return await self.reply_ok([])
浏览器控制台:
错误或我错过的任何东西? 请提前帮助我解决。
我认为您可能已经在aiohttp文档中查看了有关文件上传服务器的示例。 但是,该代码段含糊不清,并且该文档无法很好地说明自身。
在研究了一段时间之后,我发现request.multipart()
实际上产生了一个MultipartReader
实例,该实例每次调用.next()
都会处理一个字段的multipart/form-data
请求,从而产生另一个BodyPartReader
实例。
在您无法正常工作的代码中, image = await reader.next()
该行实际上从表单数据中读取了整个字段,您无法确定它实际上是哪个字段。 它可能是token
字段, key
字段, filename
段, aaa
字段...或其中的任何一个。 因此,在您无法正常工作的示例中,该post_image
协程函数将仅处理请求数据中的单个字段,并且您不能十分确定它是否为aaa
文件字段。
这是我的代码段,
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”。 Content-Disposition
标头中的filename
应由浏览器本身自动填写,因此无需担心filename
。
顺便说一句,当处理请求中的文件上载时, data = await request.post()
将占用大量内存来加载文件数据。 所以request.post()
应该包括文件上传,使用时要避免request.multipart()
来代替。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.