在没有 multipart/form-data 的情况下在 Flask 中 ReSTfully 上传文件
ReSTfully upload file in Flask without multipart/form-data
我正在尝试在不使用任何类型 multipart/form-data
的情况下将二进制文件上传到 Flask 端点。我想简单地 POST
或 PUT
文件中的数据到端点,并将其保存到服务器上的文件中。我能找到的唯一例子,以及其他问题中讨论的唯一方法,使用 multipart/form-data
.
以下 "works",但 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
没有区别。
问题可能出在您使用的 curl 命令上。手册页推荐--data-binary:"This posts data exactly as specified with no extra processing whatsoever." --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,它是请求的来源 object。
curl 命令使用 content-type header 作为 'application/octet-stream' 很好。在这种情况下,Flask 似乎没有对此做任何事情,但它可以帮助更普遍地使用代理或其他情况下的数据。
关于高效处理大文件,您可能需要查看 request stream property,get_data 内部使用它来读取数据。
您尝试过使用 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()
我正在尝试在不使用任何类型 multipart/form-data
的情况下将二进制文件上传到 Flask 端点。我想简单地 POST
或 PUT
文件中的数据到端点,并将其保存到服务器上的文件中。我能找到的唯一例子,以及其他问题中讨论的唯一方法,使用 multipart/form-data
.
以下 "works",但 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
没有区别。
问题可能出在您使用的 curl 命令上。手册页推荐--data-binary:"This posts data exactly as specified with no extra processing whatsoever." --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,它是请求的来源 object。
curl 命令使用 content-type header 作为 'application/octet-stream' 很好。在这种情况下,Flask 似乎没有对此做任何事情,但它可以帮助更普遍地使用代理或其他情况下的数据。
关于高效处理大文件,您可能需要查看 request stream property,get_data 内部使用它来读取数据。
您尝试过使用 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()