You need to enable JavaScript to run this app. 如何将读取JSON的XMLHttpRequest代码封装为可主动调用的函数
优惠活动
大模型
产品
解决方案
定价
更多

如何将读取JSON的XMLHttpRequest代码封装为可主动调用的函数

可主动调用的封装方案

你现有代码已经实现了基础回调式封装,我们可以优化为更通用、无业务绑定的可复用请求函数,同时修复原有代码未判断readyState的逻辑漏洞(会导致回调被多次触发),提供两种常用实现:

1. 回调式封装(兼容你原有调用习惯)

/**
 * 通用GET请求JSON文件
 * @param {string} url 请求地址
 * @param {function} callback 回调函数,参数为 (错误信息, 响应数据)
 */
function getJSON(url, callback) {
  const ajax = new XMLHttpRequest();
  ajax.open('GET', url, true);
  ajax.responseType = 'json';
  ajax.onreadystatechange = function () {
    // 必须判断请求完成状态
    if (ajax.readyState !== 4) return;
    if (ajax.status === 200) {
      callback(null, ajax.response);
    } else {
      callback(new Error(`请求失败,状态码:${ajax.status}`), ajax.response);
    }
  };
  // 捕获网络异常
  ajax.onerror = function () {
    callback(new Error('网络请求异常'), null);
  };
  ajax.send();
}

调用示例(实现你原有的业务逻辑):

// 任意位置主动调用即可
getJSON('games.json', function (err, data) {
  if (err) {
    console.log('Ocorreu um erro', err);
    return;
  }
  const bets = document.getElementById('bets-description');
  bets.innerHTML = '';
  bets.textContent = data.types[0].description; // 优先用textContent避免XSS风险
});

2. Promise式封装(更现代,支持async/await调用)

如果项目环境支持ES6,更推荐这种写法,避免回调嵌套问题:

/**
 * 通用GET请求JSON文件(Promise版)
 * @param {string} url 请求地址
 * @returns {Promise<any>} 响应数据Promise
 */
function getJSON(url) {
  return new Promise((resolve, reject) => {
    const ajax = new XMLHttpRequest();
    ajax.open('GET', url, true);
    ajax.responseType = 'json';
    ajax.onreadystatechange = function () {
      if (ajax.readyState !== 4) return;
      if (ajax.status === 200) {
        resolve(ajax.response);
      } else {
        reject(new Error(`请求失败,状态码:${ajax.status}`));
      }
    };
    ajax.onerror = function () {
      reject(new Error('网络请求异常'));
    };
    ajax.send();
  });
}

调用示例:

// 普通then链式调用
getJSON('games.json')
  .then(data => {
    const bets = document.getElementById('bets-description');
    bets.innerHTML = '';
    bets.textContent = data.types[0].description;
  })
  .catch(err => {
    console.log('Ocorreu um erro', err);
  });

// async/await 调用(更简洁)
async function loadBetsDescription() {
  try {
    const data = await getJSON('games.json');
    const bets = document.getElementById('bets-description');
    bets.innerHTML = '';
    bets.textContent = data.types[0].description;
  } catch (err) {
    console.log('Ocorreu um erro', err);
  }
}
// 主动触发调用
loadBetsDescription();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 02:27:01