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

如何从Marvel API获取全量数据集并实现全局角色搜索

实现漫威角色全局搜索的两种方案

你的核心问题是当前搜索仅过滤已加载的单页数据,要实现全局搜索,有两种可行方案,根据需求选择:


方案一:利用Marvel API自带搜索参数(推荐)

Marvel API的/characters端点支持nameStartsWith参数,可直接返回名称以指定字符串开头的所有角色,由API端处理搜索逻辑,无需拉取全量数据,性能更优。

修改步骤:

  1. 更新getMarvelCharacters函数,支持传入搜索参数:
// 新增全局变量存储当前搜索词
let currentSearchTerm = null;

const getMarvelCharacters = async function(searchTerm = currentSearchTerm){
  currentSearchTerm = searchTerm; // 更新当前搜索状态
  const url = `http://gateway.marvel.com/v1/public/characters?`
  const searchparam  =  new URLSearchParams({
    ts : timestamp,
    apikey: publicKey,
    hash:hashVal,
    limit: resultsPerPage,
    offset: offset
  }) 
  // 若有搜索词,添加API搜索参数
  if(searchTerm){
    searchparam.append('nameStartsWith', searchTerm);
  }
  const response = await fetch(url + searchparam)
  try {
    if(!response.ok){
      throw new Error('network response is not okay')
    }
    const data = await response.json()
    const totalNumOfChar = data.data.total
    console.log(totalNumOfChar)
    let characters  = data.data.results
    displayCharacters(characters)
    console.log(characters)
    return { characters, total: totalNumOfChar }

  } catch (error) {
    console.error('There was an error:', error)
  }
}
  1. 修改searchCharacters函数,点击搜索时重置分页并触发带参数的API请求:
const searchCharacters =  async function(){
  button.addEventListener('click', async (event)=>{
    event.preventDefault()
    const searchTerm  = searchInput.value.trim().toLowerCase()
    // 重置分页状态
    currentPage = 1
    offset = 0
    // 调用带搜索参数的接口
    await getMarvelCharacters(searchTerm)
  })
}
  1. 分页逻辑自动适配:原有的分页按钮代码无需额外修改,getMarvelCharacters会自动带上当前搜索词,确保分页仅针对搜索结果。

方案二:本地缓存全量角色数据(支持任意位置包含搜索)

如果需要实现名称任意位置包含的搜索(比如搜man匹配Spider-Man、Iron Man),Marvel API无直接支持参数,需先拉取全量数据到本地缓存,再进行本地过滤。

修改步骤:

  1. 新增全局变量存储全量数据与状态:
let allCharacters = []; // 存储所有漫威角色
let currentFilteredCharacters = []; // 存储当前搜索过滤结果
let isAllDataLoaded = false; // 标记全量数据是否加载完成
  1. 新增全量数据拉取函数:
const fetchAllCharacters = async function(){
  let total = 0;
  let currentOffset = 0;
  allCharacters = [];
  // 先获取角色总数
  const initialUrl = `http://gateway.marvel.com/v1/public/characters?${new URLSearchParams({
    ts: timestamp,
    apikey: publicKey,
    hash: hashVal,
    limit: 100 // 每次拉取100条,减少请求次数
  })}`;
  const initialResponse = await fetch(initialUrl);
  const initialData = await initialResponse.json();
  total = initialData.data.total;

  // 循环拉取所有数据
  while(currentOffset < total){
    const url = `http://gateway.marvel.com/v1/public/characters?${new URLSearchParams({
      ts: timestamp,
      apikey: publicKey,
      hash: hashVal,
      limit: 100,
      offset: currentOffset
    })}`;
    const response = await fetch(url);
    const data = await response.json();
    allCharacters.push(...data.data.results);
    currentOffset += 100;
  }
  isAllDataLoaded = true;
  console.log('全量角色数据加载完成,共', allCharacters.length, '条');
}
  1. 更新搜索与分页逻辑:
// 页面加载时启动全量数据拉取
fetchAllCharacters();

const searchCharacters =  async function(){
  button.addEventListener('click', async (event)=>{
    event.preventDefault()
    const searchTerm  = searchInput.value.trim().toLowerCase()
    currentFilteredCharacters = [];
    currentPage = 1;

    if(!searchTerm) {
      // 搜索词为空,回到全量数据分页展示
      offset = 0;
      getMarvelCharacters();
      return;
    }

    // 若全量数据未加载,先加载
    if(!isAllDataLoaded){
      await fetchAllCharacters();
    }

    // 本地过滤全量数据
    currentFilteredCharacters = allCharacters.filter(char => 
      char.name.toLowerCase().includes(searchTerm)
    );
    // 展示第一页过滤结果
    const startIndex = (currentPage - 1) * resultsPerPage;
    const pageData = currentFilteredCharacters.slice(startIndex, startIndex + resultsPerPage);
    displayCharacters(pageData);
  })
}

// 修改分页按钮逻辑,适配搜索结果分页
const getPaginationButtonResults = function(){
  const next = document.querySelector('.right')
  const prev = document.querySelector('.left')
  next.addEventListener('click', async (event)=>{
    event.preventDefault()
    if(currentFilteredCharacters.length){
      // 处于搜索状态,分页过滤结果
      const maxPage = Math.ceil(currentFilteredCharacters.length / resultsPerPage);
      if(currentPage < maxPage){
        currentPage++;
        const startIndex = (currentPage - 1) * resultsPerPage;
        const pageData = currentFilteredCharacters.slice(startIndex, startIndex + resultsPerPage);
        displayCharacters(pageData);
      }
    } else {
      // 正常分页全量数据
      currentPage++
      offset+=resultsPerPage
      await getMarvelCharacters()
    }
  })
  prev.addEventListener('click', async (event)=>{
    event.preventDefault()
    if(currentFilteredCharacters.length){
      // 处于搜索状态
      if(currentPage > 1){
        currentPage--;
        const startIndex = (currentPage - 1) * resultsPerPage;
        const pageData = currentFilteredCharacters.slice(startIndex, startIndex + resultsPerPage);
        displayCharacters(pageData);
      }
    } else {
      // 正常分页
      currentPage--
      if(currentPage>0){
        offset-=resultsPerPage
        await getMarvelCharacters()
      }
    }
  })
}

内容的提问来源于stack exchange,提问作者F Adam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:48:09