原生JS使用fetch调用API渲染国家数据到HTML页面问题排查
问题原因
你的代码存在两个直接触发报错、导致渲染失败的问题:
- Promise链式调用逻辑错误:你在
response.json()后接的第一个回调仅执行了console.log(data),没有返回任何值。Promise链中,下一级.then接收的参数是上一级回调的返回值,无返回值时参数自然为undefined,这就是你拿到data is undefined报错的直接原因。同时你写了不必要的Promise嵌套,破坏了链式调用的传值逻辑。 - 接口返回结构理解错误:你调用的REST Countries接口返回值本身就是国家信息构成的数组,不存在
data.results这一层属性,直接遍历接口返回的数组即可,多余的.results取值也会触发报错。
修正后可直接运行的代码
JavaScript 部分
function displayAll() { const countriesContainer = document.getElementById("countries-container"); const requestUrl = "https://restcountries.com/v3.1/all"; fetch(requestUrl) .then(response => { // 先校验请求状态,接口报错时提前抛出错误 if (!response.ok) { throw new Error(`请求异常,状态码:${response.status}`); } return response.json(); }) .then(countriesData => { // 清空容器原有内容,避免重复加载时内容叠加 countriesContainer.innerHTML = ''; // 遍历国家数组生成卡片 countriesData.forEach(country => { const countryCard = document.createElement("div"); // 给卡片加类名,方便后续写CSS样式 countryCard.classList.add("country-card"); // 填充卡片内容,对可能不存在的字段做空值兼容 countryCard.innerHTML = ` <h3 class="country-name">${country.name.common}</h3> <p class="country-population">人口:${country.population.toLocaleString()}</p> <p class="country-capital">首都:${country.capital?.[0] || '暂无数据'}</p> <p class="country-region">所属区域:${country.region}</p> `; countriesContainer.appendChild(countryCard); }) }) .catch(error => { // 统一捕获请求、渲染阶段的错误 console.error("国家信息加载失败:", error); countriesContainer.innerHTML = '<p class="error-tip">信息加载失败,请刷新页面重试</p>'; }) }
HTML 部分
你原有HTML结构基本可用,无需大幅调整:
<body onload="displayAll()"> <header>国家信息列表</header> <div class="container" id="countries-container"> <!-- 国家卡片将自动插入此处 --> </div> <script src="./assets/scripts.js"></script> </body>
补充说明
- 后续写CSS时直接针对
.country-card类设置样式即可,比如设置边框、内边距、圆角,配合Flex/Grid实现多列卡片布局。 - 代码中对可能不存在的字段(比如部分国家没有首都数据)做了兼容处理,不会因为个别字段缺失导致整个渲染流程中断。
- 增加了错误捕获逻辑,无论是接口请求失败还是代码运行异常,都不会出现控制台未捕获的Promise报错,同时会给用户展示友好的失败提示。
内容的提问来源于stack exchange,提问作者Cristiane DSC
相关产品推荐
相关产品推荐

