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

Node/Express GET请求与XMLHttpRequest readyState异常问题求助

解决XMLHttpRequest readyState无法到达4及onload提前触发的问题

我仔细看了你的代码,核心问题出在事件绑定的方式上——你把函数调用的结果直接赋值给了事件处理属性,而不是传递函数本身的引用。这就导致函数在代码执行到那一行时立刻运行,而不是在AJAX事件触发时才执行,自然就看不到后续的状态变化了。

问题拆解

1. 错误的事件绑定方式

你写的这两行代码是关键问题:

myRequest.onload = writeResponseText2(myRequest);
myRequest.onreadystatechange = writeResponseText(myRequest);

当你在函数后面加()时,代码会立即执行该函数,并把执行结果(这里是undefined,因为你的函数没有返回值)赋值给事件属性。此时XMLHttpRequest的readyState还是0(未初始化状态),所以writeResponseText只会触发一次,后续状态变化时不会再调用它。

2. load事件的参数传递误区

你用addEventListener绑定了load和error事件,但没有正确利用事件对象获取请求实例。实际上,浏览器触发事件时会自动传递事件对象,通过这个对象的target属性就能拿到对应的XMLHttpRequest实例。

修正后的代码

前端JavaScript代码

function writeResponseText() {
  // 这里的this指向当前的XMLHttpRequest实例
  console.log("onreadystatechange")
  console.log(this.status)
  console.log(this.readyState)
  console.log(this.responseText)
  if(this.readyState === XMLHttpRequest.DONE && this.status === 200) {
    mainSection.innerHTML = this.responseText;
  }
}

// 处理load事件的函数
function transferResult(event) {
  // 通过event.target获取请求对象
  const myRequest = event.target;
  if(myRequest.status === 200) {
    mainSection.innerHTML = myRequest.responseText;
  }
}

// 处理error事件的函数
function transferResult2(event) {
  console.error("请求出错了", event);
}

function getRESTResponse() {
  var url = "http://localhost:3000";
  var myRequest = new XMLHttpRequest();
  
  // 正确绑定事件:传递函数引用,不要加()
  myRequest.addEventListener("load", transferResult);
  myRequest.addEventListener("error", transferResult2);
  
  myRequest.open("GET", url);
  // GET请求不需要设置Content-Type(这个头用于标识请求体格式,GET通常没有请求体)
  // myRequest.setRequestHeader("Content-Type", "text/plain");
  
  // 正确绑定onreadystatechange:传递函数引用
  myRequest.onreadystatechange = writeResponseText;
  
  myRequest.send();
}

后端Express代码优化(可选)

可以用cors中间件简化跨域配置,比手动写响应头更规范:

const express = require("express");
const cors = require("cors");
const app = express();

// 自动处理跨域请求头
app.use(cors());

app.get('/',function(request,response){
  console.log('Received');
  response.type('text/plain');
  response.send("Get Handled");
  console.log(response.headersSent);
});

app.listen(3000, () => console.log('Listening on port 3000'));

关键修正说明

  • 传递函数引用而非调用函数:把writeResponseText(myRequest)改成writeResponseText,这样XMLHttpRequest会在状态变化时自动调用该函数,且this会指向当前请求实例。
  • 利用事件对象获取请求实例:在addEventListener绑定的函数中,通过event.target拿到请求对象,就能获取响应数据了。
  • 移除多余的请求头:GET请求不需要设置Content-Type,这个头只在发送请求体(如POST)时才需要。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:46:20