You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI POST处理文件返回JSON无法在React显示,response.data为undefined

问题解决:React调用FastAPI接口后response.data为undefined及结果展示

问题原因分析

  • Fetch API使用错误:fetch返回的Response对象没有直接的data属性,必须通过.json()或.text()方法解析响应体才能获取实际数据。
  • 后端返回格式问题:当前后端返回的是DataFrame.to_json()生成的JSON字符串,FastAPI会将其作为纯文本返回(Content-Type为text/plain),前端需要额外解析才能转换成可操作的JSON对象。

解决方案

步骤1:优化FastAPI后端代码

将返回的JSON字符串改为直接返回Python字典,让FastAPI自动处理为标准JSON响应(Content-Type: application/json),简化前端解析流程:

@read_file.post("/upload_followers")
async def create_upload_followers(followers_file: UploadFile, following_file: UploadFile):
    """
    处理Instagram格式的关注者和已关注列表,返回未回关的用户列表
    """
    try:
        if not (followers_file.content_type == 'application/json' and following_file.content_type == 'application/json'):
            raise ValueError('无效文件格式,请上传JSON文件。')
        
        # 读取并解析文件
        followers_read = await followers_file.read()
        following_read = await following_file.read()
        followers_data = json.loads(followers_read)
        following_data = json.loads(following_read)
        
        # 提取用户名
        valores_followers = [inner_item['value'] for item in followers_data for inner_item in item.get("string_list_data", [])]
        valores_following = [inner_item['value'] for item in following_data['relationships_following'] for inner_item in item.get("string_list_data", [])]
        
        # 数据处理
        df_followers = pd.DataFrame(valores_followers, columns=['username'])
        df_following = pd.DataFrame(valores_following, columns=['username'])
        result1 = pd.merge(df_following, df_followers, on='username', how='left', indicator=True)
        result1['_merge'] = result1['_merge'].map({'left_only':'unfollow', 'both':'keep'})
        df_result = result1[result1['_merge'] == 'unfollow']
        
        # 生成本地文件(可选)
        df_result.to_json('file.json')
        
        # 返回字典格式,FastAPI自动转为JSON响应
        return df_result.to_dict('records')
    
    except Exception as e:
        return JSONResponse(content={'error': str(e)}, status_code=400)

步骤2:修改React前端代码

新增状态存储返回结果,正确解析Fetch响应,并渲染结果列表:

import { useState } from "react";

function FileForm() {
    const [fileFollowers, setFileFollowers] = useState(null);
    const [fileFollowing, setFileFollowing] = useState(null);
    const [unfollowList, setUnfollowList] = useState([]); // 存储未回关用户列表

    const handleFileInputChangeFollowers = (event) => {
        setFileFollowers(event.target.files[0]);
    };

    const handleFileInputChangeFollowing = (event) => {
        setFileFollowing(event.target.files[0]);
    };

    const handleSubmit = async (event) => {
        event.preventDefault();
        if (!fileFollowers || !fileFollowing) return;

        const formData = new FormData();
        formData.append('followers_file', fileFollowers);
        formData.append('following_file', fileFollowing);

        try {
            const endpoint = "http://localhost:8000/upload_followers";
            const response = await fetch(endpoint, {
                method: "POST",
                body: formData
            });

            if (response.ok) {
                console.log("文件上传成功!");
                // 解析标准JSON响应
                const data = await response.json();
                console.log("未回关用户列表:", data);
                setUnfollowList(data); // 将结果存入状态
            } else {
                const errorData = await response.json();
                console.error("文件上传失败:", errorData.error);
            }

        } catch(error) {
            console.error("请求出错:", error);
        }
    };

    return (
        <div style={{ maxWidth: 800, margin: '2rem auto', padding: '0 1rem' }}>
            <h1>上传Instagram关注数据</h1>

            <form onSubmit={handleSubmit}>
                <div style={{ marginBottom: "20px" }}>
                    <input 
                        type="file" 
                        onChange={handleFileInputChangeFollowers}
                        accept=".json" // 限制仅上传JSON文件
                        required
                    />
                    <span style={{ margin: '0 1rem' }}>关注者文件</span>
                    
                    <input 
                        type="file" 
                        onChange={handleFileInputChangeFollowing}
                        accept=".json"
                        required
                    />
                    <span>已关注列表文件</span>
                </div>

                <button type="submit" disabled={!fileFollowers || !fileFollowing}>
                    上传并分析
                </button>
            </form>

            {fileFollowers && <p>已选择关注者文件:{fileFollowers.name}</p>}
            {fileFollowing && <p>已选择已关注列表文件:{fileFollowing.name}</p>}

            {/* 渲染未回关用户列表 */}
            {unfollowList.length > 0 && (
                <div style={{ marginTop: '2rem' }}>
                    <h2>未回关你的用户(共{unfollowList.length}人)</h2>
                    <ul style={{ listStyle: 'none', padding: 0 }}>
                        {unfollowList.map((item, index) => (
                            <li key={index} style={{ padding: '0.5rem', borderBottom: '1px solid #eee' }}>
                                {item.username}
                            </li>
                        ))}
                    </ul>
                </div>
            )}
        </div>
    );
}

export default FileForm;

兼容旧后端代码的方案

如果不想修改后端,前端需要先读取响应文本再解析JSON:

const text = await response.text();
const data = JSON.parse(text);

内容的提问来源于stack exchange,提问作者Simon Londoño R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:22:22