JS选文件即自动上传时Flask端request.files为空问题
错误原因
你的代码存在3个核心问题,导致后端收不到文件:
- 前端传参逻辑错误:
JSON.file是不存在的无效属性,根本取不到选中的文件对象;且普通JSON格式的POST请求无法携带二进制文件内容,必须用FormData对象封装文件数据。 - jQuery AJAX默认配置会拦截文件传输:使用jQuery传FormData时,必须关闭默认的数据处理和Content-Type自动设置,否则jQuery会把FormData转成普通字符串,后端无法识别为文件上传请求。
- 后端逻辑错误:
request.files是Flask框架的ImmutableMultiDict文件存储对象,无法直接被jsonify序列化返回,必须通过前端定义的字段名取出具体文件对象后,再做处理和响应。
额外注意:你贴的前端代码只创建了input元素,没有将其插入到页面DOM树中,用户无法看到并点击触发文件选择。
修正后可运行代码
前端JS代码
// 动态创建文件选择按钮 const downLoadBtn = document.createElement('input'); downLoadBtn.id = 'downloadBtn'; downLoadBtn.type = 'file'; downLoadBtn.onchange = upload; // 将按钮插入页面,否则用户无法点击选择文件 document.body.appendChild(downLoadBtn); function upload() { const fileInput = document.getElementById('downloadBtn'); const selectedFile = fileInput.files[0]; if (!selectedFile) return; // 用FormData封装文件,upload_file是后端读取文件用的字段名 const formData = new FormData(); formData.append('upload_file', selectedFile); $.ajax({ type: "POST", url: '/upload', dataType: 'json', data: formData, // 禁止jQuery处理数据、自动设置请求头,否则文件传输失败 processData: false, contentType: false, success: function (response) { console.log(response); } }); }
后端Flask代码
from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload(): # 路由已限制仅接受POST请求,无需重复判断请求方法 upload_file = request.files.get('upload_file') if not upload_file: return jsonify({"code": 400, "msg": "未接收到上传文件"}), 400 # 此处可添加自定义文件处理逻辑,例如保存到本地 # upload_file.save(f"./save_dir/{upload_file.filename}") print(f"接收到上传文件:{upload_file.filename}") return jsonify({"code": 200, "msg": "上传成功", "filename": upload_file.filename}) if __name__ == '__main__': app.run(debug=True)
上述实现完全满足你选择文件后自动触发上传的需求,不需要额外添加提交按钮。注意前后端的文件字段名必须保持一致,否则后端无法正确读取到上传的文件。
内容的提问来源于stack exchange,提问作者Chrisp
相关产品推荐
相关产品推荐

