我正在使用flask-socketio和eventlet运行Flask生产服务器,并且尝试提交包含要上传的文件的表单时,Flask无法读取整个请求。当文件超过几个kb(大约50kb或更多)时,就会发生这种情况。我要上传的文件是60kb .txt文件,每行有一个单词。较小的文件大小为1-2kb,事情按预期进行。
def get_file(request):
if 'uploadFile' not in request.files:
return redirect(request.url)
return = request.file['uploadFile']
做了一些测试,我能够确定代码没有通过request.files
检查。例如,我将尝试print(request.files)
,并且代码不会从那里继续前进,而只会挂起。
我了解Flask的内置方法可能不是最有效的,所以我找到了一个streaming-form-data
库,可以协助加载大文件,因此可以作为替代库来实现
def get_file(request):
parser = StreamingFormDataParser(headers=request.headers)
parser.register('file', FileTarget('/temp/file.txt')
while True:
chunk = request.stream.read(8192)
if not chunk:
break
parser.data_received(chunk) # add read bytes to file
socketio.sleep(1)
该文件仍无法完成上传,但是我发现尝试执行chunk = request.stream.read(8192)
时该文件停止了。这不会立即发生,通常会在第4-5次迭代左右停止。据我了解,在有和没有socketio.sleep()
的情况下进行了测试,据我了解,需要更多时间的任务可能需要这样做。
我使用Flask Dev Server做了更多测试,发现如果我使用app.run(threaded=True)
,它将按预期完成,并且代码将继续。但是,我无法使用socketio.run()
main.py
和eventlet使它正常工作
import eventlet
eventlet.monkey_patch()
from app import app, socketio
if __name__ == "__main__":
# app.run(threaded=True) # This will work and finish loading the file
socketio.run(app) # does not work
在while
循环读取流期间,我没有收到任何错误,它只是继续获取下一个chunk = request.stream.read(8192)
答案 0 :(得分:0)
找到了我需要的解决方案,事实证明,这并非归功于Flask。在我的POST中,我只需要包含chunking: true
,从那里开始看来一切正常。
例如
$.ajax({
type: 'POST',
chunking: true,
data: form_data,
contentType: false,
});
作为测试,我还原了上面所做的更改(尽管无论如何这些更改可能都会变得更好),并确认它是有效的。