微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flask request.stream.read在使用SocketIO上传文件时停止

如何解决Flask request.stream.read在使用SocketIO上传文件时停止

我正在使用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)

解决方法

找到了我需要的解决方案,事实证明,这并非归功于Flask。在我的POST中,我只需要包含chunking: true,从那里开始看来一切正常。

例如

$.ajax({
    type: 'POST',chunking: true,data: form_data,contentType: false,});

作为测试,我还原了上面所做的更改(尽管无论如何这些更改可能都会变得更好),并确认它是有效的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。