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

JavaScript调用API偶现TypeError 读取question属性失败

报错根因

这个偶发报错是数组索引越界导致的,和API返回的字段合法性无关,触发逻辑非常明确:

  • 调用接口时传了amount=10参数,返回的data.results是固定长度为10的数组,合法索引范围是0到9
  • 你写的随机数生成逻辑Math.floor(Math.random() * 11)会生成0到10之间的整数,包含了超出数组范围的索引值10
  • 当随机数刚好命中10时,data.results[10]的取值是undefined,此时读取.question属性就会抛出你看到的类型错误。

为什么报错偶发、且报错时题目仍能正常展示

  • 随机数命中10的概率大概是1/11,属于概率事件,自然没法稳定复现
  • 你的循环写的是i从0到i<=10,一共会执行11次,每次取到题目都会直接覆盖triviaQ的innerHTML:如果索引越界刚好发生在最后一次循环,前10次已经完成了DOM渲染,题目已经显示在页面上了,此时才抛出错误,就会出现「控制台报错但功能看起来正常」的现象。
  • 额外提一句:这个循环本身是冗余逻辑,前10次给innerHTML的赋值都会被后一次覆盖,用户最终只能看到最后一次取到的题目,前面的DOM操作全是无效执行。
修复方法

调整随机数生成范围,删掉无效循环即可,修正后的核心代码如下:

const api_url = 'https://opentdb.com/api.php?amount=10&difficulty=easy&type=boolean'
const triviaQ = document.getElementById("triviaQuestion")
let question_data = ""

async function display() {
    const response = await fetch(api_url);
    // 增加响应状态判断,避免接口异常时触发额外报错
    if (!response.ok) return
    const data = await response.json()
    const randNum = Math.floor(Math.random() * data.results.length);
    question_data = data.results[randNum]
    triviaQ.innerHTML = question_data.question
}

display()

优化提示:直接基于data.results.length计算随机索引上限,后续如果调整接口的amount参数,也不需要手动修改随机数计算逻辑,从根源上避免索引越界问题。

内容的提问来源于stack exchange,提问作者Rebja A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:30:53