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

API数据获取成功(304 Not Modified)但页面无法加载问题排查

问题排查:API数据获取成功但页面无法加载(304 Not Modified)

问题描述

API数据已成功获取,但页面无法加载展示,请求返回状态码为304 Not Modified。以下是相关HTML结构、原可正常运行的JavaScript代码,以及重构后出现问题的新JavaScript代码,需排查原因。


相关代码

HTML结构

<article data-index="1" data-status="inactive">    
    <div class="content" id="articleImage2">

        <p id="hiddenObject"> Enter details <br>
            <select id="branch">
                <option disabled selected>Branch</option>
                <option value="etc">ETC</option>
                <option value="mech">Mech</option>
                <option value="civil">Civil</option>
                <option value="pei">PEI</option>
              </select>
              <select id="semester">
                <option disabled selected>Semester</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
              </select><p>&nbsp;</p>
              <button class="form-button" type="button" onclick="navigate()">
                Let's go!!! <i class="fas fa-rocket"></i>
              </button>
        </p>
        <p>&nbsp;</p>
        <div>
          <p>Question papers
            <ul>
              <li>Loading... ..</li>
            </ul>
          </p>          
        </div>
    </div>
  </article>

原可正常运行的JavaScript代码

// forms
let typeValue = function () {
  var branch = document.getElementById("branch").value;
  var semester = document.getElementById("semester").value;
  document.getElementById("hiddenObject").style.display = "none";
  var type = `${branch}-${semester}`;
  return type;
}

function queryQuestionPaper(dataIn) {
  fetch(URL)
  .then((res) => res.json())
  .then(({ result }) => {

    let list = document.querySelector("ul");
    let firstListItem = document.querySelector("ul li");

    if (result.length > 0) {
      // 移除占位内容
      list.removeChild(firstListItem);
      result.forEach((data) => {

        if(data.type == dataIn) {
          let link = document.createElement('a');
          let linkItem = document.createElement("li");
  
          link.textContent = data.name;
          link.href= data.pdfUrl;
  
          linkItem.appendChild(link)
          list.appendChild(linkItem)
        }
      })
    }
  }).catch((err) => console.error(err));
}

if (window.location.pathname !== "/html/about.html") {
  queryQuestionPaper(typeValue);
}

重构后的JavaScript代码

表单跳转部分

// forms
function navigate() {
  var branch = document.getElementById("branch").value;
  var semester = document.getElementById("semester").value;

  const baseUrl = `./${branch}-${semester}.html`;
  window.location = baseUrl; 
}

说明:新URL由当前页面URL与构造的URL拼接而成,构造的URL会以斜杠(/)分隔添加到当前URL末尾。

类型解析部分

// queries
// 根据页面类型选择查询条件
let type = function typeMaker() {
  const currentUrl = window.location.pathname;
  const urlParts = currentUrl.split("/");
  const lastPart = urlParts[urlParts.length - 1];

  const types = {
  "etc": [1, 2, 3, 4, 5, 6, 7, 8],
  "mecha": [1, 2, 3, 4, 5, 6, 7, 8],
  "civil": [1, 2, 3, 4, 5, 6, 7, 8],
  "pei": [1, 2, 3, 4, 5, 6, 7, 8]
  };

  for (const [prefix, suffixes] of Object.entries(types)) {
    for (const suffix of suffixes) {
      const expected = `${prefix}-${suffix}.html`;
      if (lastPart === expected) {
       return `${prefix}-${suffix}`;
      }
    }
  }
}
let typeValue = type();

说明:types对象为键值对集合,键代表类别(如"etc"、"mecha"、"civil"),值为数字数组(如[1,2,3,4,5,6,7,8])。外层循环通过Object.entries()和解构赋值遍历types条目,内层循环遍历数字数组,生成预期URL并与当前URL最后部分匹配,匹配成功则返回${prefix}-${suffix}格式的字符串。

数据查询渲染部分

function queryQuestionPaper() {
  fetch(URL)
  .then((res) => res.json())
  .then(({ result }) => {

    let list = document.querySelector("ul");
    let firstListItem = document.querySelector("ul li");

    if (result.length > 0) {
      // 移除占位内容
      list.removeChild(firstListItem);
      result.forEach((data) => {

        if(data.type == typeValue) {
          let link = document.createElement('a');
          let linkItem = document.createElement("li");
  
          link.textContent = data.name;
          link.href= data.pdfUrl;
  
          linkItem.appendChild(link)
          list.appendChild(linkItem)
        }
      })
    }
  }).catch((err) => console.error(err));
}

if (window.location.pathname !== "/html/resources.html" && window.location.pathname !== "/html/about.html") {
  queryQuestionPaper();
}

排查分析

  1. 分支名称拼写不一致:表单中Mech分支的value是mech,但重构代码的types对象里写的是mecha,导致URL匹配失败,typeValue返回undefined,后续data.type == typeValue的过滤条件永远不成立,没有内容渲染。
  2. 304缓存问题:304状态码表示浏览器使用本地缓存的响应,如果之前缓存了不匹配或空数据,会导致新请求无法获取最新内容,页面自然无法展示正确数据。
  3. 全局变量依赖问题:typeValue作为全局变量,若页面加载时URL解析逻辑未执行完成,会导致其值异常,影响后续过滤。
  4. 无匹配数据时的处理缺失:当没有匹配的数据或API返回空时,页面仍会显示占位符或无提示,用户无法判断状态。

修复方案

1. 修正分支拼写不一致

将types对象中的"mecha"改为"mech",与表单选项value保持一致:

const types = {
  "etc": [1, 2, 3, 4, 5, 6, 7, 8],
  "mech": [1, 2, 3, 4, 5, 6, 7, 8],
  "civil": [1, 2, 3, 4, 5, 6, 7, 8],
  "pei": [1, 2, 3, 4, 5, 6, 7, 8]
};

2. 处理304缓存问题

在fetch请求中添加缓存控制参数,强制获取最新数据:

fetch(URL, {
  cache: 'no-cache' // 或使用'reload'强制重新请求
})

3. 优化类型解析与全局变量问题

将typeValue的赋值和查询函数调用放在DOM加载完成事件中,避免DOM未就绪的问题,同时将typeValue作为参数传入查询函数,减少全局依赖:

document.addEventListener('DOMContentLoaded', () => {
  const typeValue = type();
  if (window.location.pathname !== "/html/resources.html" && window.location.pathname !== "/html/about.html") {
    queryQuestionPaper(typeValue);
  }
});

// 修改queryQuestionPaper函数接收参数
function queryQuestionPaper(typeValue) {
  // ... 原有逻辑,将全局typeValue替换为传入的参数
}

4. 增加异常与无数据提示

完善查询函数,处理无匹配数据、API空结果、请求错误等情况,给用户明确反馈:

function queryQuestionPaper(typeValue) {
  fetch(URL, { cache: 'no-cache' })
  .then((res) => res.json())
  .then(({ result }) => {
    const list = document.querySelector("ul");
    const firstListItem = document.querySelector("ul li");

    if (result.length > 0) {
      list.removeChild(firstListItem);
      // 先过滤匹配数据
      const matchedData = result.filter(data => data.type === typeValue);
      if (matchedData.length === 0) {
        const noDataItem = document.createElement("li");
        noDataItem.textContent = "未找到对应试卷";
        list.appendChild(noDataItem);
        return;
      }
      matchedData.forEach((data) => {
        const link = document.createElement('a');
        const linkItem = document.createElement("li");
        link.textContent = data.name;
        link.href = data.pdfUrl;
        link.target = "_blank"; // 可选,新窗口打开链接
        linkItem.appendChild(link);
        list.appendChild(linkItem);
      });
    } else {
      firstListItem.textContent = "暂无数据";
    }
  }).catch((err) => {
    console.error(err);
    const list = document.querySelector("ul");
    const firstListItem = document.querySelector("ul li");
    firstListItem.textContent = "加载失败,请稍后重试";
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:00:59