如何正确显示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
相关产品推荐
相关产品推荐

