通过 AJAX 上传文件在 Flask 端返回空字典
Posted
技术标签:
【中文标题】通过 AJAX 上传文件在 Flask 端返回空字典【英文标题】:Posting file upload via AJAX returns empty dictionary on Flask side 【发布时间】:2021-12-09 12:13:27 【问题描述】:我有一个 Flask 应用程序在我添加登录功能之前一直在工作。我遇到的问题是我有一个用户可以上传文件的模式。
<p>Upload Photo</p>
<form method="POST" name="upload_pic" id="upload_pic" enctype="multipart/form-data">
<input type="file" class="custom-file-input" name="exampleInputFile" id="exampleInputFile" aria-describedby="fileHelp">
<label class="custom-file-label" for="exampleInputFile">
Select file...
</label>
<button type="button" class="btn btn-success" data-dismiss="modal" id="AddNotesSubmit">Submit</button>
然后AJAX调用上传文件:
// add notes post
$('#AddNotesSubmit').on('click', function(e)
var notes = $("#note_text").val();
var schedule_id = $("#noteSchID").text();
console.log(notes);
e.preventDefault();
$.ajax(
type: "POST",
url: "/",
data: AddNotes: "", schedule_id: schedule_id, notes: notes ,
success:function(response)
$('#response').text(JSON.stringify(response));
);
var fullPath = $("#exampleInputFile").val();
var filename = fullPath.replace(/^.*[\\\/]/, '');
const form = $('#upload_pic')[0];
const pic = new FormData(form);
console.log(form);
console.log(pic);
console.log(filename);
if (filename != '')
$.ajax(
type: "POST",
url: "/upload_pic",
data: pic,
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
);
$('#modalAddNotes').modal('hide');
);
);
最后是我用来调试的 Flask 代码:
@app.route('/upload_pic', methods=['POST'])
def upload_pic():
print(' request.files: %s' %request.files)
files = request.files.get('files[]')
print(' files: %s' %files)
python端的命令行输出为:
request.files: ImmutableMultiDict([])
files: None
所以它返回一个空字典。以前,当我使用:
uploaded_pic = request.files['exampleInputFile']
它有效,但现在包含该代码会引发 400 错误,因为 'exampleInputFile'
是 request.files
字典中的无效键。我从路由中删除了@login_required
,它没有改变任何东西。
【问题讨论】:
request.files.get('exampleInputFile')
你从哪里得到files[]
?这不是文件输入的名称。
在另一个线程中提到,如果是多文件上传,'files[]' 应该返回所有已上传文件的列表... get('') 中的'exampleInputFile' 返回空字典出现同样的错误。
参数必须匹配文件输入的name="xxx"
属性。那个“其他线程”大概有name="files[]"
感谢您的反馈。我知道 name = 'XXX' 必须匹配 request.files['XXX'] 但是当我这样做时,我收到此错误:werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent an request that this服务器无法理解。 KeyError:'exampleInputFile'
【参考方案1】:
在我看来,很难看出您的代码为什么不起作用。在您的示例中,表单标签未关闭。此外,您没有描述您的 javascript 代码是如何执行的。尽管我假设您使用的是单击事件,但我使用提交事件测试了您的代码。我得出的结论是代码有效。
这是我用于测试的变体:
<p>Upload Photo</p>
<form method="POST" name="upload_pic" id="upload_pic" enctype="multipart/form-data">
<input type="file" class="custom-file-input" name="exampleInputFile" id="exampleInputFile" aria-describedby="fileHelp">
<label class="custom-file-label" for="exampleInputFile">
Select file...
</label>
<button type="submit" class="btn btn-success" data-dismiss="modal" id="AddNotesSubmit">Submit</button>
</form>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script type="text/javascript">
$(document).ready(function()
$('form[name="upload_pic"]').submit(function(event)
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
$.ajax(
type: 'POST',
url: '/upload_pic',
data: formData,
processData: false,
contentType: false
).done((data) =>
console.log(data);
)
);
);
</script>
@app.route('/upload_pic', methods=['POST'])
def upload_pic():
if 'exampleInputFile' in request.files:
file = request.files['exampleInputFile']
if file.filename != '':
# handle file here!
return jsonify(success=True)
return jsonify(success=False)
【讨论】:
我为该事件添加了完整的 js 代码。上半部分处理模态提交的文本部分,它工作正常。 谢谢!当我为它制作一个带有新路线的空白页面时,你的代码就工作了。是页面中的其他东西弄乱了它。 @TonyD。对不起,我在你写的代码中找不到任何错误。恐怕我帮不了你。以上是关于通过 AJAX 上传文件在 Flask 端返回空字典的主要内容,如果未能解决你的问题,请参考以下文章