对 .txt 文件执行 POST 请求时出现 Axios 错误

问题描述 投票:0回答:1

我正在使用 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

这是我在控制台中遇到的错误:

enter image description here

我在 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 端点都工作正常,我已经被这个问题困扰了一个星期,我需要一些帮助。如果您需要更多信息或想查看项目的更多部分/脚本,请随时询问:)

javascript python reactjs flask react-fullstack
1个回答
0
投票

我可以看到您的代码中存在 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。

© www.soinside.com 2019 - 2024. All rights reserved.