求助:Flask无法识别前端上传文件的问题如何解决
Flask无法接收前端上传文件的解决方案
问题场景
前端通过XMLHttpRequest上传文件后,Flask后端无法识别上传的内容,控制台输出如下:
ImmutableMultiDict([]) ImmutableMultiDict([]) b'' 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
涉及的代码如下:
前端HTML
<input class="input" type="file" name="file" id="imageInp"></input> <button class="addBtn" id="addBtn">Add</button>
原前端JS
var HttpClient = function () { this.get = function (aUrl, img) { var anHttpRequest = new XMLHttpRequest(); var fdata = new FormData(); fdata.append("file", img); anHttpRequest.open("POST", aUrl, true); anHttpRequest.setRequestHeader("Content-type", "multipart/form-data"); anHttpRequest.send(fdata); } } document.getElementById("addBtn").onclick = function() { image = document.getElementById("imageInp").files[0]; var client = new HttpClient(); client.get(*url_here*, image); }
原Flask后端
@app.route('*url_here*', methods=['POST']) def foo(): try: print(request.form) print(request.files) print(request.data) frame = request.files['file'].read() return 'OK', 200, {'ContentType':'application/json'} except Exception as e: log('Main', e) return 'Error', 400, {'ContentType':'application/json'}
错误原因
- 手动设置Content-Type破坏请求结构:使用
FormData时,浏览器会自动生成包含boundary的multipart/form-data请求头(例如multipart/form-data; boundary=----WebKitFormBoundaryxyz),这个boundary是分隔表单数据的关键标识。手动设置Content-type会丢失该标识,导致Flask无法解析请求体。 - 路由格式错误:Flask的路由URL必须以
/开头,否则无法正确匹配请求路径。 - 变量未声明:前端的
image变量未用var/let声明,虽不直接导致上传失败,但属于不良编码习惯。
修复步骤
1. 修正前端JS代码
- 移除手动设置
Content-type的代码 - 为
image变量添加声明 - 修正函数名(避免
get和POST请求语义冲突)
修改后的JS代码:
var HttpClient = function () { this.post = function (aUrl, img) { var anHttpRequest = new XMLHttpRequest(); var fdata = new FormData(); fdata.append("file", img); anHttpRequest.open("POST", aUrl, true); // 移除手动设置Content-type的行,由浏览器自动生成 anHttpRequest.send(fdata); } } document.getElementById("addBtn").onclick = function() { let image = document.getElementById("imageInp").files[0]; if (!image) { alert("请先选择文件"); return; } var client = new HttpClient(); client.post('/upload', image); // 替换为实际后端接口路径 }
2. 修正Flask后端代码
- 修正路由URL格式(以
/开头) - 添加文件存在性检查,避免直接读取不存在的文件报错
修改后的Flask代码:
from flask import Flask, request, jsonify import logging app = Flask(__name__) logging.basicConfig(level=logging.INFO) log = logging.getLogger('Main') @app.route('/upload', methods=['POST']) def foo(): try: print(request.form) print(request.files) print(request.data) # 检查文件是否存在 if 'file' not in request.files: return jsonify({'error': '未上传文件'}), 400 file = request.files['file'] if file.filename == '': return jsonify({'error': '未选择文件'}), 400 frame = file.read() print(f"接收文件大小:{len(frame)} 字节") return jsonify({'status': 'OK'}), 200 except Exception as e: log.error('错误信息:%s', e) return jsonify({'error': str(e)}), 400 if __name__ == '__main__': app.run(debug=True)
验证结果
修改完成后,选择文件点击Add按钮,后端控制台会输出类似内容:
ImmutableMultiDict([]) ImmutableMultiDict([('file', <FileStorage: 'test.jpg' ('image/jpeg')>)]) b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x08\x06\x06\x07\x06\x05\x08\x07\x07\x07\t\t\x08\n\x0c\x14\r\x0c\x0b\x0b\x0c\x19\x12\x13\x0f...' 接收文件大小:12345 字节
此时Flask可正常接收并读取上传文件,返回200 OK响应。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

