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

Angular In-memory-web-api获取单个对象时抛出404错误求助

解决Angular in-memory-web-api获取单个Podcast时的404错误

嘿,我之前也踩过这个坑!in-memory-web-api默认是通过id字段来匹配单个资源的,而你现在用name作为路由参数来查询,它根本识别不了这个匹配规则,所以才会返回404。下面给你几个实用的解决办法,你可以根据自己的场景选:

方法一:自定义InMemoryDataService的请求处理

你可以在InMemoryDataService里重写get方法,专门处理基于name的查询请求。这样不管是路径参数还是其他规则,都能自己控制:

import { InMemoryDbService, RequestInfo } from 'angular-in-memory-web-api';
import { Podcast } from './podcast';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
  createDb() {
    const podcasts = [
      { id: 1, name: 'angular-tips', title: 'Angular入门技巧' },
      { id: 2, name: 'rxjs-deep-dive', title: 'RxJS深度解析' }
    ];
    return { podcasts };
  }

  // 重写get方法,处理按name匹配的请求
  get(reqInfo: RequestInfo) {
    // 匹配 /podcasts/xxx 这样的路径
    const nameMatch = reqInfo.url.match(/\/podcasts\/([^\/]+)$/);
    if (nameMatch) {
      const targetName = nameMatch[1];
      const podcasts = reqInfo.collection as Podcast[];
      const matchedPodcast = podcasts.find(podcast => podcast.name === targetName);
      
      if (matchedPodcast) {
        // 返回找到的资源
        return reqInfo.utils.createResponse$(() => ({
          body: matchedPodcast,
          status: 200
        }));
      } else {
        // 没找到的话返回404(这步可选,也可以返回空)
        return reqInfo.utils.createResponse$(() => ({
          body: { error: 'Podcast不存在' },
          status: 404
        }));
      }
    }
    // 其他请求交给默认逻辑处理
    return undefined;
  }
}

方法二:改用查询参数来请求

如果不想改内存服务的逻辑,也可以调整你的podcast-service,用查询参数传递name,in-memory-web-api会自动帮你过滤:

// podcast.service.ts
getPodcast(name: string): Observable<Podcast> {
  // 用?name=xxx的形式传递参数
  const requestUrl = `${this.podcastsBaseUrl}?name=${name}`;
  return this.http.get<Podcast[]>(requestUrl).pipe(
    // 因为返回的是匹配的数组,取第一个元素就行
    map(podcasts => podcasts[0])
  );
}

这种方式不用改内存服务,简单直接,适合快速调试。

方法三:把name设为资源的id字段

如果你的Podcast的name是唯一的(不会重复),那最简单的办法就是把id字段直接设为name的值,这样in-memory-web-api的默认匹配规则就生效了:

// InMemoryDataService里的模拟数据
const podcasts = [
  { id: 'angular-tips', name: 'angular-tips', title: 'Angular入门技巧' },
  { id: 'rxjs-deep-dive', name: 'rxjs-deep-dive', title: 'RxJS深度解析' }
];

然后你的服务请求代码不用改,还是原来的:

getPodcast(name: string): Observable<Podcast> {
  const url = `${this.podcastsBaseUrl}/${name}`;
  return this.http.get<Podcast>(url);
}

这样in-memory-web-api会把路径里的name当成id去匹配,自然就能找到对应的Podcast了。

最后别忘了检查一下组件里传递的name参数是不是正确,比如路由里的:name有没有正确传递到组件的getPodcast方法里哦!

内容的提问来源于stack exchange,提问作者Tom O'Brien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:09:29