我正在使用表单 enctype="multipart/form-data"和 Flask 将多个文件上传到服务器。
我的问题是选择的第一个文件始终为空(0 大小)。其余所有选定的文件都以正确的大小上传,只有第一个选定的文件以 0 的大小上传,使其无法使用。
这看起来与以下问题相关:File is empty after saving flask uploads
查看 bukman 的评论:
“我意识到,当您在表单中使用“多个”属性时,Flask 有一个习惯,即包含一个与其中一个文件附件(通常是第一个附件)名称和详细信息完全相同的空文件上传”
这真的是真的吗?因为这似乎正是发生在我身上的事情,对我来说这是一种非常奇怪的行为方式。
这是我的表格:
<form method="post" enctype="multipart/form-data">
<table class="center">
<tr>
<td class="font-weight-bold" align="left">file.tcx:</td>
<td class="font-weight-bold" align="left"><input type="file"
name="tcxfiles[]" multiple class="form-control-file"/></td>
</tr>
</table>
<div style="text-align: center"><input class="btn btn-primary btn-lg"
type="submit">
</div>
</form>
在 Python/Flask 中我以这种方式处理文件:
files = request.files.getlist("tcxfiles[]")
for each_file in files:
if each_file and allowed_file(each_file.filename):
filename = secure_filename(each_file.filename)
each_file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
allowed_file 是一个函数,我仅使用它来过滤上传的文件并仅允许 .tcx 文件 secure_file_name函数是确保文件名安全的函数。
两者均从 flask 文档中复制:
https://flask.palletsprojects.com/en/1.1.x/patterns/fileuploads/
如上所述,如果我上传多个文件,第一个文件将以长度 0 存储,其他文件以正确的长度存储。
如果我只选择一个文件,那么它会与文件 0 一起存储。
我的flask版本是1.1.1
>>> import pkg_resources
>>> pkg_resources.get_distribution('flask').version
'1.1.1'
任何提示都会有用,因为我正在挠头,试图理解这种行为。
预期结果是所有上传的文件都具有正确的大小,而不是始终有一个文件大小为 0
最佳答案
我尝试重现这个场景。我可以上传多个图像文件,没有任何错误。
目录结构:
.
├── app.py
├── requirements.txt
├── static
│ └── uploads
└── templates
└── file_upload.html
requirements.txt
:
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.1
pkg-resources==0.0.0
Werkzeug==0.15.5
app.py
:
import os
from flask import Flask, flash, request, redirect, url_for, render_template
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = os.path.join('static', 'uploads')
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
files = request.files.getlist("multiple_files[]")
filenames = []
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
filenames.append(filename)
flash("Uploaded files: {}".format(", ".join(filenames)))
return render_template("file_upload.html")
file_upload.html
:
<!doctype html>
<html>
<head>
<title>Upload Multiple Files</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<h1>Upload Multiple Files</h1>
<form method="post" enctype="multipart/form-data" action={{url_for("upload_file")}}>
<input type="file" name="multiple_files[]" multiple>
<input type="submit" value="Upload">
</form>
</body>
</html>
屏幕截图:
上传两张图片之前:
上传两张图片后:
ls -l
表示第一个文件不为空。我可以从 /static/uploads
文件夹中查看这两个图像。
关于python-3.x - 通过 enctype ="multipart/form-data"上传多个文件,第一个上传的文件大小始终为0,其余都可以,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57490511/