【问题标题】:ReSTfully upload file in Flask without multipart/form-data在没有多部分/表单数据的情况下,在 Flask 中完全上传文件
【发布时间】:2016-08-22 11:00:34
【问题描述】:

我正在尝试将二进制文件上传到 Flask 端点,而不使用任何类型的 multipart/form-data。我想简单地将文件内的数据POSTPUT 发送到端点,并将其保存到服务器上的文件中。我能找到的唯一示例,以及其他问题中讨论的唯一方法,使用multipart/form-data

以下“有效”,但 SHA256 哈希通常不匹配,而上传为 form-data 可以正常工作。

@application.route("/rupload/<filename>", methods=['POST', 'PUT'])
def rupload(filename):
    # Sanity checks and setup skipped.

    filename = secure_filename(filename)
    fileFullPath = os.path.join(UPLOAD_FOLDER, filename)

    with open(fileFullPath, 'wb') as f:
        f.write(request.get_data())

    return jsonify({
        'filename': filename,
        'size': os.path.getsize(fileFullPath)
    })

此外,上述方法在内存方面的效率非常低。有没有办法通过某种类型的缓冲流将其写入输出文件?谢谢!

编辑:这是我测试的方式:

curl -v -H 'Content-Type: application/octet-stream' -X POST --data @test.zip https://example.com/test/rupload/test.zip

编辑: --data-binary 没有区别。

【问题讨论】:

    标签: python rest flask multipartform-data


    【解决方案1】:

    问题可能是您使用的 curl 命令。手册页推荐 --data-binary:“这完全按照指定的方式发布数据,无需任何额外处理。” --data 参数是 --data-ascii 的同义词。可能不需要 -X 参数,因为它应该默认为 POST。

    curl -v -H 'Content-Type: application/octet-stream' -X POST --data-binary @test.zip https://example.com/test/rupload/test.zip
    

    request.get_data 调用中有其他选项可以帮助它们在某处被覆盖。但看起来这应该在服务器端工作。禁用缓存功能可能对您的用例尤其有益。

    f.write(request.get_data(cache=False, as_text=False, parse_form_data=False))
    

    如果是服务器端,您可能需要深入挖掘 Werkzeug get_input_stream,它是请求对象的来源。

    curl 命令将 content-type 标头用作“application/octet-stream”,这很好。在这种情况下,Flask 似乎没有做任何事情,但它可以帮助更一般的使用,让数据被代理或其他情况破坏。

    关于有效处理大文件,您可能需要查看 request stream property,这是 get_data 在内部用于从中读取数据的内容。

    【讨论】:

    • 嗯。但该文件应被视为二进制文件。如何获取原始二进制数据?
    • 如果您解释一下如何在客户端发布数据,也许会有所帮助。
    • 非常感谢您的回复。出于某种原因,这两个更改(curl 命令和request.get_data())都没有导致上传文件的哈希值发生任何变化。这让我很困惑。
    • 所有链接都坏了:-(
    • 更新了损坏的链接。
    【解决方案2】:

    你尝试过使用 hashlib 吗?

    import hashlib
    ...
    @application.route("/rupload/<filename>", methods=['POST', 'PUT'])
    def rupload(filename):
        # Sanity checks and setup skipped.
    
        filename = secure_filename(filename)
        fileFullPath = os.path.join(UPLOAD_FOLDER, filename)
        file_hash = hashlib.sha256()
        with open(fileFullPath, 'wb+') as f:
            input = request.get_data()
            f.write(input)
            file_hash.update(input)
            ...
        fileDigest = file_hash.hexdigest()
    

    【讨论】:

    • 对不起,这与散列无关,但谢谢!我确实用过haslib。
    • 你知道吗,你是对的......我没有以二进制模式打开文件进行哈希处理。谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2014-05-14
    相关资源
    最近更新 更多