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

JavaScript异步函数无法获取jsonplaceholder数据,DOM无法渲染内容

解决JavaScript异步请求jsonplaceholder API失败及DOM渲染问题

问题根源

  1. 无效的API地址:obtenerComentarios函数中使用了占位符URL,无法发起有效请求
  2. 字段匹配错误:jsonplaceholder的评论接口返回数据不含userId字段,原代码无法通过该字段筛选作者对应的评论;评论通过postId关联文章,文章通过userId关联用户,需通过这个关联关系实现筛选

修正后的完整代码

HTML(无需修改,保持原结构即可)

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog - Lista de Comentarios</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.flex {
display: flex;
flex-wrap: wrap;
}
.flex article {
width: calc(50% - 20px);
margin: 10px;
padding: 10px;
border: 2px solid black;
}
.flex article:nth-child(even)
{
background-color: #f0f0f0;
}
select {
border: 2px solid tomato;
width: 80%;
padding: 20px;
margin: 20px auto 0px auto;
display: block;
font-size: 150%;
}
hr {
margin: 20px;
}
</style>
</head>
<body>
<header>
<select id="selectAutor">
<option value="" selected>Selecciona un autor</option>
<option value="1">Autor 1</option>
<option value="2">Autor 2</option>
<option value="3">Autor 3</option>
<!-- Añadir más opciones según sea necesario -->
</select>
<hr>
</header>
<section id="comentarios" class="flex">
<!-- esta es la superficie iterable que hay que repetir por cada comentario -->
<article>
<h3>Nombre del autor</h3>
<p>Email: correo@dominio.com</p>
<p>Comentario:</p>
<p>Texto del comentario</p>
</article>
</section>
<script src="script.js"></script>
</body>
</html>

JavaScript

document.addEventListener('DOMContentLoaded', () => {
    // 缓存已获取的数据,避免重复请求API
    let comentariosCache = null;
    let postsCache = null;

    // 获取所有文章(用于关联用户与评论)
    async function obtenerPosts() {
        if (postsCache) return postsCache;
        const url = 'https://jsonplaceholder.typicode.com/posts';
        try {
            const response = await fetch(url);
            if (!response.ok) throw new Error(`HTTP错误!状态码:${response.status}`);
            postsCache = await response.json();
            return postsCache;
        } catch (error) {
            console.error('获取文章失败:', error);
            throw error;
        }
    }

    // 获取所有评论
    async function obtenerComentarios() {
        if (comentariosCache) return comentariosCache;
        const url = 'https://jsonplaceholder.typicode.com/comments';
        try {
            const response = await fetch(url);
            if (!response.ok) throw new Error(`HTTP错误!状态码:${response.status}`);
            comentariosCache = await response.json();
            return comentariosCache;
        } catch (error) {
            console.error('获取评论失败:', error);
            throw error;
        }
    }

    // 筛选指定用户的所有评论
    async function obtenerComentariosPorAutor(idAutor) {
        const posts = await obtenerPosts();
        const comentarios = await obtenerComentarios();
        // 先获取该用户发布的所有文章ID
        const userPostIds = posts.filter(post => post.userId === idAutor).map(post => post.id);
        // 筛选出关联这些文章的评论
        return comentarios.filter(comentario => userPostIds.includes(comentario.postId));
    }

    // 渲染指定用户的评论到DOM
    async function mostrarComentariosPorAutor(idAutor) {
        console.log('选中的作者ID:', idAutor);
        try {
            const comentariosAutor = await obtenerComentariosPorAutor(idAutor);
            console.log('该作者的评论:', comentariosAutor);

            const contenedorComentarios = document.getElementById('comentarios');
            contenedorComentarios.innerHTML = '';

            // 处理无评论的情况
            if (comentariosAutor.length === 0) {
                contenedorComentarios.innerHTML = '<p>该作者暂无评论内容</p>';
                return;
            }

            comentariosAutor.forEach(comentario => {
                const article = document.createElement('article');
                article.innerHTML = `
                    <h3>${comentario.name}</h3>
                    <p>邮箱: ${comentario.email}</p>
                    <p>评论内容:</p>
                    <p>${comentario.body}</p>
                `;
                contenedorComentarios.appendChild(article);
            });
        } catch (error) {
            console.error('渲染评论失败:', error);
            document.getElementById('comentarios').innerHTML = '<p>加载评论时发生错误,请稍后重试</p>';
        }
    }

    // 监听作者选择下拉框的变化事件
    document.getElementById('selectAutor').addEventListener('change', event => {
        const idAutor = parseInt(event.target.value);
        if (idAutor) {
            mostrarComentariosPorAutor(idAutor);
        } else {
            // 选择空选项时重置为初始状态
            document.getElementById('comentarios').innerHTML = `
                <article>
                    <h3>Nombre del autor</h3>
                    <p>Email: correo@dominio.com</p>
                    <p>Comentario:</p>
                    <p>Texto del comentario</p>
                </article>
            `;
        }
    });
});

关键优化点

  • 替换占位符为jsonplaceholder的真实API地址,确保请求有效
  • 新增文章数据获取逻辑,通过文章-用户、评论-文章的关联关系实现按用户筛选评论
  • 加入数据缓存机制,避免重复请求API,提升页面性能
  • 增加HTTP请求状态校验,处理请求失败的场景
  • 补充空数据和错误状态的DOM提示,提升用户体验
  • 优化空选项选择时的页面重置逻辑

内容的提问来源于stack exchange,提问作者Daniel Fenoll

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:45:55