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

如何用JavaScript的fetch()加载所有JSON文件到HTML表格?

问题描述

现有文件结构如下:

  • /mysite/index.html
  • /mysite/products/ 文件夹,包含从1.json到578.json的多个JSON文件,每个文件对应单个产品,格式示例:
    [{"id":1,"name":"16' Tire Japan","stock":145}]
    
  • /mysite/script.html(与index.html关联)

index.html中包含产品表格:

<table>
   <thead>
      <th>id</th>
      <th>name</th>
      <th>stock</th>
   </thead>
   <tbody id="products"></tbody>
</table>

需求:使用JavaScript逐个获取/products/下所有存在的JSON文件,将数据填充到表格的tbody(id为products)中。

之前使用单个products.json文件的实现代码:

fetch("products.json")
  .then(function(response) {
    return response.json();
    })
  .then(function(products){
    let placeholder = document.querySelector("#products");
    let out = "";
    for(let product of products){
        out += `<tr id='tr${product.id}'>
                <td class='id'>${product.id}</td>
                <td class='name'>${product.name}</td>
                <td class='stock'>${product.stock}</td>
            </tr>`;
    }
    placeholder.innerHTML = out;
  });
解决方案

浏览器端JavaScript无法直接遍历服务器上的文件夹,因此可以通过以下两种方式实现:

方式一:按已知ID范围批量请求(适用于ID连续或已知最大ID的情况)

如果已知产品ID的范围(比如1到578),可以循环请求每个ID对应的JSON文件,忽略不存在的文件:

并行请求版本(效率更高)

const tbody = document.querySelector("#products");
const maxProductId = 578; // 替换为实际最大产品ID
const fetchTasks = [];

// 生成所有请求任务
for (let id = 1; id <= maxProductId; id++) {
  const task = fetch(`products/${id}.json`)
    .then(res => {
      if (!res.ok) throw new Error(`产品${id}不存在`);
      return res.json();
    })
    .catch(err => {
      console.log(err.message);
      return null; // 标记不存在的产品
    });
  fetchTasks.push(task);
}

// 等待所有请求完成后渲染表格
Promise.all(fetchTasks)
  .then(results => {
    let tableRows = "";
    // 过滤无效结果,将每个JSON的数组转为单个产品对象
    const validProducts = results.filter(item => item).flat();
    validProducts.forEach(product => {
      tableRows += `
        <tr id='tr${product.id}'>
          <td class='id'>${product.id}</td>
          <td class='name'>${product.name}</td>
          <td class='stock'>${product.stock}</td>
        </tr>
      `;
    });
    tbody.innerHTML = tableRows;
  })
  .catch(err => console.error("加载数据失败:", err));

串行请求版本(减少服务器并发压力)

如果担心并发请求过多,可以改用串行请求:

const tbody = document.querySelector("#products");
const maxProductId = 578;
let tableRows = "";

async function loadAllProducts() {
  for (let id = 1; id <= maxProductId; id++) {
    try {
      const res = await fetch(`products/${id}.json`);
      if (!res.ok) throw new Error();
      const [product] = await res.json(); // 取出数组中的单个产品对象
      tableRows += `
        <tr id='tr${product.id}'>
          <td class='id'>${product.id}</td>
          <td class='name'>${product.name}</td>
          <td class='stock'>${product.stock}</td>
        </tr>
      `;
    } catch {
      console.log(`跳过不存在的产品ID:${id}`);
    }
  }
  tbody.innerHTML = tableRows;
}

loadAllProducts();

方式二:后端生成文件列表(更高效推荐)

如果有后端支持,建议在服务器端生成一个包含所有存在的产品ID的列表文件(比如products/list.json),内容示例:

[1,2,3,5,7,...,578]

然后先请求这个列表,再根据列表中的ID请求对应的JSON文件,避免无效的404请求:

const tbody = document.querySelector("#products");

fetch("products/list.json")
  .then(res => res.json())
  .then(productIds => {
    const fetchTasks = productIds.map(id => 
      fetch(`products/${id}.json`).then(res => res.json())
    );
    return Promise.all(fetchTasks);
  })
  .then(allProducts => {
    let tableRows = "";
    allProducts.flat().forEach(product => {
      tableRows += `
        <tr id='tr${product.id}'>
          <td class='id'>${product.id}</td>
          <td class='name'>${product.name}</td>
          <td class='stock'>${product.stock}</td>
        </tr>
      `;
    });
    tbody.innerHTML = tableRows;
  })
  .catch(err => console.error("加载数据失败:", err));

内容的提问来源于stack exchange,提问作者Ирина Комсомольская

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:44:51