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

前端调用async fetch获取后端API数据仅返回部分内容问题

前端Fetch请求仅接收部分后端API返回数据的排查与解决

问题场景

开发课程项目时,前端用JavaScript的async fetch调用后端Java API,仅能收到部分返回数据:后端本应返回包含status和content的完整JSON,但前端只拿到{"status": "success"}。Postman调用该API完全正常,前端接收异常。

预期后端返回

{
    "status": "success",
    "content": [
        {
            "name": "ABC",
            "key": "123456"
        }
    ]
}

前端实际接收

{"status": "success"}

相关代码

前端JavaScript代码

export async function getObjectsFromS3(data) {
    const response = await fetch(url, {
        method: "GET",
        headers: {
            "Authorization": `Basic ${btoa("user:password")}`
        }
    });

    if (!response.ok) {
        throw new Error(response.status);
    }

    const result = await response.json();
    
    return result
}

后端Java代码

@RestController
@RequestMapping("/users")
public class S3Controller {
    
    @Autowired
    S3Service s3Service;

    @GetMapping("/{userName}/objects")
    public String listObjects(@PathVariable String userName, @RequestParam String prefix) {
        AuthenticationUtil.authorizeUser(userName);
        String jsonString = "";
        JSONObject jo = new JSONObject();
        JSONArray ja = new JSONArray();

        ja.put("key");
        ja.put("name");
        ja.put("size");
        ja.put("type");

        try {
            List<S3Object> objects = s3Service.listObjects(prefix);
            for (S3Object object : objects) {
                String suffix = object.key().replace(prefix, "");
                String[] suffixDir = suffix.split("/");

                if ((suffixDir.length == 1 && suffixDir[0] !== "")) {
                    String type, name, key;
                    key = object.key();

                    if (key.charAt(key.length() - 1) === '/') 
                        type = "folder";
                    else 
                        type = "file";

                    name = suffixDir[suffixDir.length - 1];

                    jsonString += object.key() + "," + name + "," + String.valueOf(object.size()) + "," + type + "\n";
                }
            }
            jo.put("status", "success");
            jo.put("content", CDL.toJSONArray(ja, jsonString));
        } catch (Exception e) {
            jo.put("status", "error");
            jo.put("message", "Error when listing files: " + e.getMessage());
        }

        return jo.toString();
    }
}

问题排查与解决方法

1. 修正Java语法错误

原代码中判断字符串非空用了!==,这是JavaScript语法,Java中字符串不等于应改为!"".equals(suffixDir[0])(避免空指针风险)。虽然Postman调用正常,但语法错误可能导致逻辑异常,先修正此问题。

2. 替换CDL拼接JSON的方式

CDL.toJSONArray通过字符串拼接生成JSON数组,容易出现格式错误(比如换行未转义),导致前端response.json()解析失败,只解析了前面的status字段。建议直接构建JSON对象数组:

// 替换原循环中的字符串拼接逻辑
JSONArray contentArray = new JSONArray();
for (S3Object object : objects) {
    String suffix = object.key().replace(prefix, "");
    String[] suffixDir = suffix.split("/");

    if (suffixDir.length == 1 && !"".equals(suffixDir[0])) {
        String type, name, key;
        key = object.key();
        type = key.charAt(key.length() - 1) == '/' ? "folder" : "file";
        name = suffixDir[suffixDir.length - 1];

        JSONObject item = new JSONObject();
        item.put("key", key);
        item.put("name", name);
        item.put("size", object.size());
        item.put("type", type);
        contentArray.put(item);
    }
}
jo.put("content", contentArray);

3. 前端添加JSON解析错误捕获

当前代码仅判断HTTP状态码,未捕获JSON解析异常。添加捕获逻辑,打印原始响应文本确认后端返回是否完整:

export async function getObjectsFromS3(data) {
    const response = await fetch(url, {
        method: "GET",
        headers: {
            "Authorization": `Basic ${btoa("user:password")}`
        }
    });

    if (!response.ok) {
        throw new Error(response.status);
    }

    try {
        const result = await response.json();
        return result;
    } catch (parseError) {
        console.error("JSON解析失败:", parseError);
        const rawText = await response.text();
        console.log("原始响应文本:", rawText);
        throw parseError;
    }
}

4. 确保后端响应头正确

后端直接返回String类型时,Spring可能未正确设置Content-Type: application/json,导致前端解析异常。可以改为返回JSONObject或手动设置响应头:

// 方式1:返回JSONObject,Spring自动处理Content-Type
@GetMapping("/{userName}/objects")
public JSONObject listObjects(@PathVariable String userName, @RequestParam String prefix) {
    // 逻辑不变,最后直接返回jo
    return jo;
}

// 方式2:手动设置响应头
@GetMapping("/{userName}/objects")
public ResponseEntity<String> listObjects(@PathVariable String userName, @RequestParam String prefix) {
    // 逻辑不变
    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .body(jo.toString());
}

内容的提问来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:39:56