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

如何从Angular Promise返回的嵌套响应中提取目标body数据?

Angular HttpClient请求返回多层body嵌套问题解决方案

嵌套问题产生原因

  • 前端调用this.http.request()底层API时,默认返回完整的HttpResponse响应对象,对象自带第一层body属性存储接口返回的原始响应内容,这是Angular HttpClient的默认设计
  • 后端接口将返回值类型定义为String,如果业务层service.fetchData()返回的是提前序列化好的JSON字符串,Spring MVC会将该字符串再次做JSON序列化转义,相当于把JSON内容包装成字符串格式返回
  • 前端配置了responseType: "json",收到响应后只会自动解析最外层的JSON结构,内层被转义包装的JSON字符串不会被自动解析,最终就形成了多层body嵌套的结构,和截图中展示的响应结构完全匹配。

多层body嵌套响应结构截图

临时提取第三层目标数据方案

如果暂时无法调整后端代码,可以直接在前端回调中逐层拆解获取目标数据,同时修正请求头配置错误(原配置中Accept、Content-Type写为text/html与JSON响应类型不匹配,会触发解析异常):

fetch = () => {   
  const url  = `${environment.api}${Paths.FetchData}${this.userId}`;
  const req: HttpRequest<any> = new HttpRequest("GET", url, {
      headers: new HttpHeaders({
          "Accept": "application/json",
          "Content-Type": "application/json"
      }),
      responseType: "json"
  });    
  this.http.request(req).toPromise().then(r => {
    // 逐层拆包获取第三层目标数据
    const targetData = r.body?.body?.body;
    console.log('提取到的目标数据:', targetData);
    return targetData;
  });
}

根源修复方案(推荐)

临时拆包方案只适配当前嵌套层级,后续接口返回结构调整就会失效,建议从前后端两端同时调整彻底解决问题:

  • 前端调整:替换底层request()调用为HttpClient提供的快捷请求方法,这类方法默认直接返回解析后的响应体内容,不会携带外层HttpResponse包装:
fetch = () => {   
  const url  = `${environment.api}${Paths.FetchData}${this.userId}`;
  // 直接调用get快捷方法,无需手动从响应对象取body
  this.http.get(url, {
    headers: new HttpHeaders({
      "Accept": "application/json"
    })
  }).toPromise().then(data => {
    console.log('接口返回数据:', data);
    return data;
  });
}
  • 后端调整:修改接口返回值类型为实际业务对象类型,不要返回手动序列化的JSON字符串,JSON序列化工作统一交给Spring MVC的消息转换器处理,从根源避免重复序列化包装:
// 将返回值从String替换为实际业务DTO类型,例如下方的YourDataDto
@RequestMapping(value = "/fetchData/{userId}", method = RequestMethod.GET)
public YourDataDto fetchData(@PathVariable("userId") String userId) {
    System.out.println("calling00");
    if (!MyUtility.checkNullOrZero(Long.valueOf(userId))) {
        try {
            // 直接返回业务对象,不要提前转成JSON字符串
            return service.fetchData(Long.valueOf(userId));
        } catch (Exception e) {
            log.error("数据查询异常", e);
            // 异常场景不要直接返回null,按业务规范抛出对应异常或返回统一错误结构
            throw new RuntimeException("数据查询失败");
        }
    }
    throw new IllegalArgumentException("用户ID参数非法");
}

注意:如果当前service层的fetchData方法返回值是JSON字符串,需要先调整该方法逻辑,直接返回Java业务对象,不要在业务代码中手动做JSON序列化操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:57:13