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

使用XMLHttpRequest调用RapidAPI酒店搜索接口导致Web应用内存溢出崩溃问题求助

解决XMLHttpRequest调用RapidAPI酒店接口时的「Out of memory」错误

兄弟,我一眼就瞅出问题根源了——你写的循环是个死循环!这直接导致浏览器疯狂创建DOM元素,直到内存耗尽崩溃。

问题核心分析

你看这段循环代码:

for (let i = 0; hotelObj.length; i++) {

循环的终止条件是hotelObj.length,只要接口返回的数组长度大于0,这个条件就永远为true,i会一直递增,循环永远停不下来。浏览器不停地创建空的div.col和div.row并往页面里塞,内存直接被撑爆,自然抛出「Out of memory」错误。

修正后的完整代码

我给你把代码改好了,还加了一些实用的容错和优化:

const btn4 = document.querySelector('#hotelBtn')
btn4.addEventListener('click', function showHotels(e) {
  var userQuery = $('#hotelQuery').val();
  
  // 先拦截空输入,避免无效请求
  if (!userQuery.trim()) {
    alert('请输入酒店搜索关键词');
    return;
  }

  const xhr = new XMLHttpRequest();
  xhr.addEventListener("readystatechange", function () {
    if (this.readyState === this.DONE) {
      // 先处理API请求失败的情况
      if (this.status !== 200) {
        console.error('API请求失败:', this.statusText);
        document.getElementById('query_results').innerHTML = '<p>获取酒店信息失败,请稍后重试</p>';
        return;
      }

      try {
        var hotelObj = JSON.parse(this.responseText)
        console.log(hotelObj)
        var myContainer = document.getElementById('query_results')
        
        // 清空容器,避免多次点击堆积重复内容
        myContainer.innerHTML = '';
        
        // 兼容接口可能的返回结构:有些接口会把数组放在data/results字段里
        const hotelList = Array.isArray(hotelObj) ? hotelObj : (hotelObj.data || hotelObj.results || []);
        
        // 正确的循环终止条件:i < 数组长度
        for (let i = 0; i < hotelList.length; i++) {
          const hotel = hotelList[i];
          var myCol = document.createElement('div')
          myCol.setAttribute('class', 'col')
          
          // 给空div添加实际的酒店信息(根据接口返回字段调整)
          myCol.innerHTML = `
            <h5>${hotel.name || '未知酒店'}</h5>
            <p>${hotel.address || '暂无地址信息'}</p>
          `;

          var myRow = document.createElement('div')
          myRow.setAttribute('class', 'row')
          myRow.append(myCol)
          myContainer.append(myRow)
        }

        // 无搜索结果时给用户提示
        if (hotelList.length === 0) {
          myContainer.innerHTML = '<p>没有找到匹配的酒店,请更换关键词试试</p>';
        }
      } catch (err) {
        // 处理JSON解析失败的异常
        console.error('解析响应数据失败:', err);
        document.getElementById('query_results').innerHTML = '<p>解析酒店信息失败,请稍后重试</p>';
      }
    }
  });

  // 用encodeURIComponent处理用户输入,避免特殊字符破坏URL格式
  const requestUrl = `https://booking-com.p.rapidapi.com/v1/hotels/locations?locale=en-gb&name=${encodeURIComponent(userQuery)}`;
  xhr.open("GET", requestUrl);
  xhr.setRequestHeader("x-rapidapi-host", "booking-com.p.rapidapi.com");
  xhr.setRequestHeader("x-rapidapi-key", "mykey");
  xhr.send();
  e.preventDefault()
})

额外优化建议

  1. 批量DOM操作:如果返回的酒店数量很多,建议用DocumentFragment批量创建元素,减少DOM重绘次数:
    const fragment = document.createDocumentFragment();
    for (let i = 0; i < hotelList.length; i++) {
      // 创建元素的逻辑不变
      fragment.append(myRow);
    }
    myContainer.append(fragment);
    
  2. 添加防抖:防止用户频繁点击按钮发送重复请求,比如设置300ms的延迟:
    let debounceTimer;
    btn4.addEventListener('click', function showHotels(e) {
      clearTimeout(debounceTimer);
      debounceTimer = setTimeout(() => {
        // 原请求逻辑
      }, 300);
      e.preventDefault();
    })
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 23:27:28