使用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() })
额外优化建议
- 批量DOM操作:如果返回的酒店数量很多,建议用
DocumentFragment批量创建元素,减少DOM重绘次数:const fragment = document.createDocumentFragment(); for (let i = 0; i < hotelList.length; i++) { // 创建元素的逻辑不变 fragment.append(myRow); } myContainer.append(fragment); - 添加防抖:防止用户频繁点击按钮发送重复请求,比如设置300ms的延迟:
let debounceTimer; btn4.addEventListener('click', function showHotels(e) { clearTimeout(debounceTimer); debounceTimer = setTimeout(() => { // 原请求逻辑 }, 300); e.preventDefault(); })
内容的提问来源于stack exchange,提问作者Tolkienist Coder
相关产品推荐
相关产品推荐

