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

如何正确显示Fetch获取的Rick and Morty API剧集名称?

问题解决:Rick and Morty API 获取角色首次剧集名称返回undefined

问题描述

我正在使用Rick and Morty API开发网站,已成功从三个不同端点获取数据,但在获取角色首次出现的剧集名称时返回undefined。

问题原因

角色数据中的episode字段是剧集API地址的数组,并非直接包含剧集名称的对象,所以直接访问item.episode.name会得到undefined。你当前仅获取了角色列表数据,没有根据这些URL去请求对应的剧集详情。

解决方案

下面提供两种可行的处理方式:

方案一:单剧集请求(直观易实现)

修改JavaScript代码,对每个角色的首个剧集URL单独发起请求,拿到名称后再渲染:

function getCharacters(done) {
    fetch("https://rickandmortyapi.com/api/character")
        .then(response => response.json())
        .then(data => {
            done(data);
        })
        .catch(error => {
            console.error("Error fetching characters:", error);
        });
}

// 新增:根据剧集URL获取剧集名称的函数
async function getFirstEpisodeName(episodeUrl) {
    try {
        const response = await fetch(episodeUrl);
        const episodeData = await response.json();
        return episodeData.name;
    } catch (error) {
        console.error("Error fetching episode:", error);
        return "Unknown";
    }
}

// 异步处理角色渲染,等待剧集请求完成
getCharacters(async data => {
    const main = document.querySelector("main");
    for (const item of data.results) {
        // 获取第一个剧集的名称
        const firstEpisodeName = await getFirstEpisodeName(item.episode[0]);
        
        const article = document.createRange().createContextualFragment(/*html*/`
        <article class="character-card">
            <div class="image-container">
                <img src="${item.image}" alt="Character">
            </div>
            <div class="character-info">
                <div class="section">
                    <h2>${item.name}</h2>
                    <span class="status">${item.status} - ${item.species}</span>
                </div>
                <div class="section">
                    <span class="greytext">Last known location:</span>
                    <span>${item.location.name}</span>
                </div>
                <div class="section">
                    <span class="greytext">First seen in:</span>
                    <span>${firstEpisodeName}</span>
                </div>
            </div>
        </article>
        `);
        main.append(article);
    }
});

方案二:批量请求(高效减少请求数)

先收集所有角色的首个剧集URL,去重后批量请求,再映射到角色数据上:

async function fetchAllEpisodes(episodeUrls) {
    // 去重URL避免重复请求
    const uniqueUrls = [...new Set(episodeUrls)];
    const episodePromises = uniqueUrls.map(url => fetch(url).then(res => res.json()));
    const episodes = await Promise.all(episodePromises);
    // 创建URL到剧集名称的映射表
    return episodes.reduce((map, episode) => {
        map[episode.url] = episode.name;
        return map;
    }, {});
}

getCharacters(async data => {
    // 收集所有角色的首个剧集URL
    const firstEpisodeUrls = data.results.map(item => item.episode[0]);
    const episodeNameMap = await fetchAllEpisodes(firstEpisodeUrls);
    
    const main = document.querySelector("main");
    data.results.forEach(item => {
        const firstEpisodeName = episodeNameMap[item.episode[0]] || "Unknown";
        const article = document.createRange().createContextualFragment(/*html*/`
        <article class="character-card">
            <div class="image-container">
                <img src="${item.image}" alt="Character">
            </div>
            <div class="character-info">
                <div class="section">
                    <h2>${item.name}</h2>
                    <span class="status">${item.status} - ${item.species}</span>
                </div>
                <div class="section">
                    <span class="greytext">Last known location:</span>
                    <span>${item.location.name}</span>
                </div>
                <div class="section">
                    <span class="greytext">First seen in:</span>
                    <span>${firstEpisodeName}</span>
                </div>
            </div>
        </article>
        `);
        main.append(article);
    });
});

其他无需修改的代码

CSS代码

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

h1{
    text-align: center;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

main {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 18px;
}

.image-container{
    display: flex;
}

.image-container img{
    width: 229.2px;
    height: 220px;
}

article{
    padding: 10px;
    box-shadow: 0px 0px 1px #000;
}

.character-card{
    display: flex;
    margin: 13.5px;
}

.character-info{
    display: flex;
    flex-direction: column;
    padding: 13.5px;
    position: relative;
}

.section{
    display: flex;
    flex-direction: column;
    width: 343.8px;
    height: 64.33px;
}

.greytext{
    color: rgb(158,158,158);
}

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Rick and Morty API</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <h1>Rick and Morty API</h1>
    <main></main>

    <script src="index.js"></script>
</body>

</html>

内容的提问来源于stack exchange,提问作者alessi.gg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:57:44