POST上传TXT文件时Axios报错及Flask后端序列化问题求助
问题:Flask+React文件上传API报错:
TypeError: Object of type Response is not JSON serializable 问题背景
开发Flask+React项目时,API端点负责接收前端上传的.txt文件、运行分析脚本并保存图表,但上传文件时前端出现Axios错误,后端终端抛出TypeError: Object of type Response is not JSON serializable。
错误信息
前端控制台错误

后端终端错误
File "/opt/anaconda3/lib/python3.11/json/encoder.py", line 180, in default raise TypeError(f'Object of type {o.__class__.__name__} ' TypeError: Object of type Response is not JSON serializable
相关代码
后端Flask接口代码
@analysis_ns.route('/upload', methods=["POST", "GET"]) class ChatAnalysisUploadResource(Resource): def get(self): return {"message": "This endpoint is only for file uploads via POST."}, 405 #@jwt_required() def post(self): """Upload a chat file, process it and return the image URLs""" try: if 'file' not in request.files: abort(400, description="No file part") file = request.files['file'] if file.filename == '': abort(400, description="No selected file") if file and allowed_file(file.filename): filename = secure_filename(file.filename) file_path = os.path.join(UPLOAD_FOLDER, filename) file.save(file_path) # 处理文件并生成图片 process_chat_file(file_path) image_paths = ['static/mensajes_enviados.png', 'static/emojis.png'] missing_images = [path for path in image_paths if not os.path.exists(path)] if missing_images: abort(500, description=f"图片未找到: {missing_images}") image_urls = { 'urls': [ url_for('static', filename='mensajes_enviados.png', _external=True), url_for('static', filename='emojis.png', _external=True) ] } # 保存结果到数据库 result_summary = ";".join(image_urls['urls']) new_analysis = ChatAnalysisResults( chat_name=filename, result_summary=result_summary ) new_analysis.save() return jsonify(image_urls), 200 abort(400, description="不允许的文件类型") # 捕获错误并返回可序列化的消息 except Exception as e: return jsonify({"error": str(e)}), 500
前端React上传组件代码
import { useState } from 'react' import PropTypes from 'prop-types' import axios from 'axios' import '../App.css' function UploadForm({ setImages }) { const [file, setFile] = useState(null); const [response, setResponse] = useState(''); const [loading, setLoading] = useState(false); const handleFileChange = (event) => { setFile(event.target.files[0]); }; const handleUpload = async () => { if (!file) { alert("请选择要上传的聊天文件。"); return; } const formData = new FormData() formData.append('file', file) // 从'chat_file'改为'file' setLoading(true) // 启动加载动画 setImages([]) // 清空之前的结果 setResponse('') // 可选:清空响应消息 console.log('加载开始'); try { const response = await axios.post('http://127.0.0.1:8080/analysis/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); console.log('响应数据:', response.data); setImages(response.data.urls); setResponse('聊天文件分析成功'); } catch (error) { console.error('文件上传错误:', error); setResponse('文件上传错误: ' + (error.response ? error.response.data.error : error.message)); } finally { setLoading(false); // 无论结果如何都停止加载动画 console.log('加载结束'); } } return ( <div className="upload-form"> <input type="file" onChange={handleFileChange} accept=".txt" /> <button onClick={handleUpload}> {loading ? '分析中' : '分析聊天记录'} </button> {response && <p>{response}</p>} {loading && ( <div className='loading'> <div className='spinner'></div> </div> )} </div> ) } UploadForm.propTypes = { setImages: PropTypes.func.isRequired, } export default UploadForm
解决方案
核心原因
Flask-RESTful的Resource类要求返回可序列化的Python字典(或元组),而jsonify()返回的是Flask原生Response对象,无法被Flask-RESTful自动序列化,因此抛出错误。
修改步骤
后端代码修正:移除所有
jsonify()调用,直接返回字典+状态码:- 成功响应替换:
# 原代码:return jsonify(image_urls), 200 return image_urls, 200 - 异常响应替换:
# 原代码:return jsonify({"error": str(e)}), 500 return {"error": str(e)}, 500
- 成功响应替换:
前端代码优化:移除手动设置的
Content-Type,Axios在传递FormData时会自动添加正确的请求头(包含boundary):// 原代码 const response = await axios.post('http://127.0.0.1:8080/analysis/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); // 修改后 const response = await axios.post('http://127.0.0.1:8080/analysis/upload', formData);额外检查:确认
process_chat_file函数没有返回Response对象,确保它仅执行文件处理逻辑,不返回不可序列化的内容。
修改后,后端可正常序列化响应,前端能正确接收数据并展示结果。
内容的提问来源于stack exchange,提问作者ivanlosarcos
相关产品推荐
相关产品推荐

