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

为何JS的readyStateChangeHandler同时返回成功与失败结果?

问题描述

在function readyStateChangeHandler(xhttp)函数中,网站能正常显示返回的表格,但该处理函数会同时输出成功与失败两种结果,且“get search result”按钮下方会显示来自该函数的错误信息。

问题原因

onreadystatechange事件会在XMLHttpRequest的readyState状态变化时触发多次,而非仅在请求完成时触发。readyState包含5个状态值:

  • 0: 未初始化
  • 1: 已打开
  • 2: 已发送
  • 3: 正在接收响应
  • 4: 响应完成

你的代码中,只要readyState不等于4或状态码不是200,就会执行失败逻辑,导致请求过程中的前4次状态变化都会触发handleStatusFailure,提前渲染错误信息。尽管最后readyState变为4且状态码200时会执行成功逻辑显示表格,但错误信息已经残留。

修复方案

修改readyStateChangeHandler函数,仅当readyState等于4(请求完成)时,再根据状态码判断成功或失败;同时在请求成功时清空错误信息容器,避免残留提示。另外修正displayObj函数中HTML字符串的语法错误(多余<td>标签、style属性分号缺失)。

修复后的完整代码:

function makeAjaxQuery() {
  // 创建XMLHttpRequest实例
  var xhttp = new XMLHttpRequest();
  // 绑定状态变化处理函数
  xhttp.onreadystatechange = function() {
    readyStateChangeHandler(xhttp);
  };
  // 异步发起GET请求
  xhttp.open("GET", "xxxxxxx-A3-Q6.json", true);
  xhttp.send();
}

// readyState状态变化处理函数
function readyStateChangeHandler(xhttp) {
  // 仅在请求完成(readyState=4)时处理结果
  if (xhttp.readyState == 4) {
    if (xhttp.status == 200) {
      // 请求成功
      handleStatusSuccess(xhttp);
      console.log('success')
    } else {
      // 请求完成但状态异常
      console.log('failure')
      handleStatusFailure(xhttp);
    }
  }
}

// 请求失败处理
function handleStatusFailure(xhttp) {
  var displayDiv = document.getElementById("display");
  displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}

// 请求成功处理
function handleStatusSuccess(xhttp) {
  // 清空错误信息容器
  var displayDiv = document.getElementById("display");
  displayDiv.innerHTML = "";
  
  var jsonText = xhttp.responseText;
  // 解析JSON响应
  var obj = JSON.parse(jsonText);
  // 渲染结果到页面
  displayObj(obj);
}

// 渲染数据为表格
function displayObj(obj) {
  var table = "";
  for (i = 0; i < 5; i++) {
    table +=
      "<tr><td>" + '<a href="' + obj.result.video[i].link + '"><img src="' + obj.result.video[i].image + '" width=200></a>' + "</td><td>" +
      '<span style="color:#DA3FA4; font-weight:bold; font-size: 30px;">' + obj.result.video[i].title + "</span>" + "<br/>" +
      '<span style="font-weight:bold;font-size: 25px;">' + obj.result.video[i].channel + "</span>" + "<br/>" +
      '<span style="font-weight:bold;font-size: 25px;">' + obj.result.video[i].view + " views" + "</span>" + "<br/>" +
      '<span style="font-weight:bold; background-color: black; color:white; font-size: 25px;">' + obj.result.video[i].length + "</span>" + "</td></tr>";
  }
  document.getElementById("test").innerHTML = '<h1>Search results</h1><br><span style="font-size: 30px;">Search keyword: Mathematics</span><br>';
  document.getElementById("demo").innerHTML = table;
}

// 绑定按钮点击事件
const start = document.getElementById("getSearch");
start.addEventListener("click", function() {
  makeAjaxQuery()
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:50:37