Angular HttpClient调用Pokémon数据API遇404,求验证解决方案正确性
Angular HttpClient获取Pokémon数据时404错误的解决办法
问题描述
我使用Angular的HttpClient模块通过服务获取Pokémon数据,根据ID获取单个Pokémon的代码如下:
export class PokemonService { getPokemonById(pokemonId: number): Observable<Pokemon | undefined> { return this.http.get<Pokemon>(`api/pokemon/${pokemonId}`).pipe( tap((response) => this.log(response)), catchError((error) => this.handleError(error, undefined)) ); } private log(response:Pokemon[]|Pokemon|undefined) { console.table(response); } private handleError (error:Error, errorValue:any ){ console.error(error); return of(errorValue); } }
同时我的路由配置如下:
const pokemonRoutes: Routes = [ { path: 'pokemon/:id', component: DetailPokemonComponent }, { path: 'edit/pokemon/:id', component: EditPokemonComponent }, { path: 'pokemons', component: ListPokemonComponent }, ];
但在获取数据时出现404错误,我确认路由配置是正确的。
我推测的解决方案:使用InMemoryDbService时,该服务要求API端点采用复数形式,需将端点名称添加"s",即正确的端点应为api/pokemons/${pokemonId}而非api/pokemon/${pokemonId}。
请问该方案是否正确,或者是否存在其他解决办法?
解决方案
你的推测是完全正确的。InMemoryDbService的默认行为遵循RESTful风格,要求API端点使用复数形式,来匹配你在内存数据库中定义的数据集名称(比如你在createDb方法中返回的是{ pokemons: [...] },那么对应的端点必须是/api/pokemons)。将请求URL改为api/pokemons/${pokemonId}后,404问题应该会解决。
除此之外,还有以下几种解决办法:
- 自定义InMemoryDbService的路由规则:如果你坚持要使用单数形式的端点,可以在InMemoryDbService的实现中重写
get方法来匹配自定义路由:
import { InMemoryDbService, HttpRequest, HttpResponse } from 'angular-in-memory-web-api'; import { of } from 'rxjs'; export class InMemoryDataService implements InMemoryDbService { createDb() { const pokemons = [ // 这里填入你的Pokémon数据 { id: 1, name: 'Bulbasaur' }, { id: 2, name: 'Ivysaur' } ]; return { pokemons }; } get(req: HttpRequest<any>, db: { pokemons: any[] }) { // 匹配/api/pokemon/:id格式的请求 const idMatch = req.url.match(/\/api\/pokemon\/(\d+)$/); if (idMatch) { const id = +idMatch[1]; const pokemon = db.pokemons.find(p => p.id === id); return pokemon ? of(new HttpResponse({ status: 200, body: pokemon })) : of(new HttpResponse({ status: 404 })); } // 其他请求交给默认逻辑处理 return undefined; } }
- 检查内存数据库的数据集命名:如果你在
createDb中返回的对象键名是单数pokemon(比如return { pokemon: [...] }),那么原端点api/pokemon/${pokemonId}也能正常工作,但这种命名不符合RESTful规范,不推荐使用。 - 确认URL拼写与大小写:InMemoryDbService默认区分URL的大小写,确保你的请求URL和内存数据库的键名大小写完全一致(比如不要写成
Api/Pokemon或api/Pokemon)。
内容的提问来源于stack exchange,提问作者Amin El Mabrouk
相关产品推荐
相关产品推荐

