我在网站上传,并使用flask作为后端。这些文件都是在一个POST请求中从客户端发送到服务器的,我正在使用getlist()
的{{1}}方法单独处理它们,并使用for循环迭代:
request
问题是我想限制上传到50mb的EACH文件的大小,但我假设if request.method == 'POST':
files = request.files.getlist('f[]')
限制了整个请求的大小。有没有办法可以评估MAX_CONTENT_LENGTH
对象中每个文件的大小,如果文件太大,就拒绝该文件?用户可以上传一定数量的文件,但每个文件需要不超过50mb。
答案 0 :(得分:3)
您可以在此处使用两条信息:
有时会设置Content-Length标头;解析确保这对于上载的实际数据是准确的。如果是这样,您可以从FileStorage.content_length
attribute获取此值。
上传的文件是文件对象(磁盘上的临时文件或类似内存文件的对象);只需在这些上使用file.seek()
和file.tell()
即可确定其大小,而无需阅读整个对象。 可能是内存中的文件对象不支持搜索,此时你应该能够将整个文件读入内存,因为它足够小而不需要临时-disk文件。
结合起来,测试单个文件大小的最佳方法是:
def get_size(fobj):
if fobj.content_length:
return fobj.content_length
try:
pos = fobj.tell()
fobj.seek(0, 2) #seek to end
size = fobj.tell()
fobj.seek(pos) # back to original position
return size
except (AttributeError, IOError):
pass
# in-memory file object that doesn't support seeking or tell
return 0 #assume small enough
然后在你的循环中:
for fobj in request.files.getlist('f[]'):
if get_size(fobj) > 50 * (1024 ** 2):
abort(413) # request entity too large
这避免了必须完全将数据读入内存。
答案 1 :(得分:-3)
将MAX_CONTENT_LENGTH设置为适合所有文件总大小的值,然后在处理之前检查每个文件的文件大小。
if request.method == 'POST':
files = request.files.getlist('f[]')
for f in files:
if len(f.read()) < (50 * 1024 * 1024):
# do something