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

无法将XHR请求响应存入JavaScript变量的原因及解决

问题原因与解决方法

这问题我太熟悉了!核心原因是异步请求的执行时机没搞对,咱们一步步拆解:

为什么直接赋值会得到null?

你写的XHR请求是异步模式(open方法第三个参数是true),调用req.send()之后,浏览器会在后台发送请求,主线程不会等待请求完成,而是继续往下执行代码。这时候你立刻执行var myJSON = req.response;,请求还在进行中,readyState还没到4(请求完成的状态),response自然还是null。

那为什么后来在控制台重新赋值能拿到数据?很简单:等你在控制台输入代码的时候,后台的请求已经完成了,readyState变成4、status是200,浏览器已经把响应数据填充到req.response里了,这时候赋值当然能拿到正确的JSON对象。

解决方法:监听请求完成事件

异步请求的正确姿势是等请求完成后再处理响应数据,我们可以通过监听load事件来实现:

方法1:使用onload回调函数

var req = new XMLHttpRequest();
req.open('get', 'https://jsonplaceholder.typicode.com/todos', true);
req.responseType = 'json';

// 当请求完成时触发这个回调
req.onload = function() {
  // 先判断请求是否成功
  if (this.status === 200 && this.readyState === 4) {
    var myJSON = this.response;
    console.log(myJSON); // 这里就能拿到正确的JSON数据了
  } else {
    console.error('请求失败:', this.status);
  }
};

req.send();

方法2:使用addEventListener监听load事件

和上面的逻辑一致,只是写法更灵活(可以绑定多个事件处理函数):

var req = new XMLHttpRequest();
req.open('get', 'https://jsonplaceholder.typicode.com/todos', true);
req.responseType = 'json';

req.addEventListener('load', function() {
  if (this.status === 200) {
    var myJSON = this.response;
    console.log(myJSON);
  }
});

req.send();

额外推荐:改用fetch API(更现代的写法)

如果你不需要兼容特别老的浏览器,更推荐用fetch,它基于Promise,写法更简洁易读:

fetch('https://jsonplaceholder.typicode.com/todos')
  .then(response => {
    if (!response.ok) {
      throw new Error('请求失败');
    }
    return response.json();
  })
  .then(myJSON => {
    console.log(myJSON);
  })
  .catch(error => {
    console.error(error);
  });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:51:24