Angular POST请求未返回正确数据问题排查
Angular POST请求无法复现Postman结果的问题排查与修复
问题背景
Postman发送POST请求体{"component": "Hero", "name": "Superman"}可正常获取数据库返回数据,但Angular服务中无法实现相同效果。
Postman返回数据示例:
{ "_embedded": { "heroValueses": [ { "idValue": 166, "idRelation": null, "key": "true", "text": "S", "id": "" }, { "idValue": 167, "idRelation": null, "key": "false", "text": "N", "id": "" } ] }, "_links": { "self": { "href": "http://localhost:8080/api/entities/heroeList/search" } }, "page": { "size": 2147483647, "totalElements": 2, "totalPages": 1, "number": 0 } }
组件中调用代码:
this.heroPower$ = this.service._lookupHero('Superman', 'Fly');
服务中原错误代码:
public _lookupHero(component: string, name: string): Observable<{ id: string, text: string }[]> { const url = this.settings.url.resHeroUrl + 'heroList/search' const header = "Here is the header"; const body = { component, name }; console.log(body, 'bodyyyyyyyyy') const res = this.http.post(url, body,{headers: header}).pipe(shareReplay(), map(response => { return response; }), catchError(err => of({err})) ); return new Observable<HeroesValues[]>().pipe(map(res => { return res.map(element => { return {id: element.key, text: element.text }; }) })); } }
问题分析
- 未实际发送HTTP请求:代码最后返回了一个新的空Observable,完全丢弃了前面用
http.post创建的请求流,导致后端根本没收到请求。 - 请求头格式错误:
headers参数必须是HttpHeaders实例,直接传字符串会导致请求头设置无效,后端可能无法正确解析请求。 - 响应数据解析错误:Postman返回的数据嵌套在
_embedded.heroValueses中,但原代码没有提取这部分数据,反而对空数组做映射。 - 错误处理逻辑问题:
catchError返回of({err})会让流继续,但这个返回值的类型和方法声明的返回类型不匹配,后续订阅会出现类型错误。
修复后的代码
首先推荐定义匹配返回结构的接口(增强类型安全性):
interface HeroResponse { _embedded: { heroValueses: HeroesValues[]; }; } interface HeroesValues { idValue: number; idRelation: number | null; key: string; text: string; id: string; }
修正后的服务方法:
import { HttpHeaders } from '@angular/common/http'; // 导入其他必要模块(如Observable、of、map、catchError、shareReplay等) public _lookupHero(component: string, name: string): Observable<{ id: string, text: string }[]> { const url = `${this.settings.url.resHeroUrl}heroList/search`; // 正确构建HttpHeaders,替换成实际业务需要的头信息 const headers = new HttpHeaders({ 'Content-Type': 'application/json', // 示例:如果需要认证头,可添加如下字段 // 'Authorization': 'Bearer ' + yourToken }); const body = { component, name }; return this.http.post<HeroResponse>(url, body, { headers }).pipe( shareReplay(), // 提取嵌套的heroValueses数组 map(response => response._embedded.heroValueses), // 转换为组件需要的{id, text}结构 map(values => values.map(element => ({ id: element.key, text: element.text }))), catchError(err => { console.error('请求英雄数据失败:', err); // 根据业务需求,可返回空数组或重新抛出错误 return of([]); }) ); }
内容的提问来源于stack exchange,提问作者Pirip
相关产品推荐
相关产品推荐

