我正在使用 Flask 和 React 开发一个项目,更具体地说,现在我正在开发一个 API 端点,该端点具有从前端接收 .txt 文件的实用程序,然后它将运行一个脚本来分析来自该文件的数据.txt 并保存与分析相关的图。
这是后端的API端点:
@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)
# Procesa el archivo y genera las imágenes
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"Imagen no encontrada: {missing_images}")
image_urls = {
'urls': [
url_for('static', filename='mensajes_enviados.png', _external=True),
url_for('static', filename='emojis.png', _external=True)
]
}
# Guardar los resultados en la base de datos
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="File type not allowed")
# Captura el error y devuelve un mensaje serializable
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("Please select a chat file to upload.");
return;
}
const formData = new FormData()
formData.append('file', file) // Cambiado de 'chat_file' a 'file'
setLoading(true) // Inicia la animación de carga
setImages([]) // Limpia los resultados anteriores
setResponse('') // Opcional: limpia el mensaje de respuesta
console.log('Loading started');
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:', response.data);
setImages(response.data.urls);
setResponse('Chat file analyzed successfully');
} catch (error) {
console.error('Error uploading the file:', error);
setResponse('Error uploading the file: ' + (error.response ? error.response.data.error : error.message));
} finally {
setLoading(false); // Detiene la animación de carga independientemente del resultado
console.log('Loading finished');
}
}
return (
<div className="upload-form">
<input type="file" onChange={handleFileChange} accept=".txt" />
<button onClick={handleUpload}>
{loading ? 'Analyzing' : 'Analyze Chat'}
</button>
{response && <p>{response}</p>}
{loading && (
<div className='loading'>
<div className='spinner'></div>
</div>
)}
</div>
)
}
UploadForm.propTypes = {
setImages: PropTypes.func.isRequired,
}
export default UploadForm
这是我在控制台中遇到的错误:
我在 VSCode 终端上看到的错误如下:
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
到目前为止,除了这个之外,所有 API 端点都工作正常,我已经被这个问题困扰了一个星期,我需要一些帮助。如果您需要更多信息或想查看项目的更多部分/脚本,请随时询问:)
我可以看到您的代码中存在 CORS 策略错误。出现这种情况是因为您正在处理两个不同的 URL,一个用于后端,一个用于前端,要解决此问题,您必须对 Flask 代码进行更改。安装
flask_cors
包并从中导入模块;
from flask_cors import cross_origin #for specific route
from flask_cors import CORS #for whole app
导入后
analysis_ns = Flask(__name__) #you might have done this in beginning your code
CORS(analysis_ns) #for enabling CORS in whole app, define it at the beginning of your code
#rest of your code
@analysis_ns.route('/upload', methods=["POST", "GET"])
@cross_origin #for enabling CORS in specific route
#rest of your code
这可能有助于解决错误。我在实习期间遇到了 CORS 政策问题,当时我使用相同的技术,即 Flask 和 React。