PHP可获取数据库数据,但Ajax无法传数据至JavaScript数组问题
问题分析与解决方案
你的核心问题出在AJAX异步逻辑执行顺序、变量作用域和this指向错误上,导致无法拿到PHP返回的产品数据并完成页面渲染。以下是具体问题点和修复方案:
问题点拆解
- 变量作用域限制:原生AJAX回调里的
products是局部变量,外部的展示函数根本访问不到; - 箭头函数的this指向错误:
xhr.onload = () => {}用了箭头函数,this不会指向XMLHttpRequest实例,导致状态判断失效,JSON解析代码从未执行; - 异步逻辑顺序错误:页面加载完成后直接调用渲染函数,但此时AJAX请求还没完成,
products变量不存在; - jQuery AJAX拼写错误:
datatype需写成dataType(jQuery对该参数大小写敏感),否则无法自动解析JSON。
修复后的完整代码(原生AJAX写法)
// 全局变量存储产品数据 let products = []; const section = document.querySelector('.cards'); const btnContainer = document.querySelector('.top ul'); // 封装AJAX请求函数 function fetchProducts() { const xhr = new XMLHttpRequest(); xhr.open('GET', 'user.php', true); // 设置响应类型为JSON,无需手动解析 xhr.responseType = 'json'; xhr.onload = function() { // 用普通函数保证this指向xhr实例 if (this.readyState === 4 && this.status === 200) { products = this.response; // 请求成功后再执行渲染和按钮生成逻辑 displayProductItems(products); displayMenuButtons(); } }; // 处理请求失败场景 xhr.onerror = function() { console.error('产品数据请求失败'); }; xhr.send(); } // 页面加载完成后发起AJAX请求 window.addEventListener('DOMContentLoaded', fetchProducts); function displayProductItems(productItems) { let displayProducts = productItems.map((item) => { return `<div class="card"> <img src="${item.image}" alt="${item.title}"> <h3>${item.title}</h3> <div class="bottom"> <span class="text-accent-2">${item.category}</span> <span class="price">$${item.price}</span> </div> </div>`; }).join(""); section.innerHTML = displayProducts; } function displayMenuButtons() { const sub_categories = products.reduce((values, item) => { if (!values.includes(item.sub_category)) { values.push(item.sub_category); } return values; }, ['all']); const buttons = sub_categories.map((sub_cat) => { return `<li><button class="filter-btn" data-id="${sub_cat}">${sub_cat}</button></li>` }).join(""); btnContainer.innerHTML = buttons; const filterBtn = document.querySelectorAll('.filter-btn'); filterBtn.forEach((btn) => { btn.addEventListener('click', (e) => { const sub_cat = e.currentTarget.dataset.id; const productsSubCat = products.filter((productItem) => { return productItem.sub_category === sub_cat; }); displayProductItems(sub_cat === 'all' ? products : productsSubCat); }); }); }
额外注意事项
- 确保PHP文件
user.php返回合法JSON格式,并且设置响应头:header('Content-Type: application/json'); - 若选择jQuery AJAX写法,需修正参数拼写并在回调中处理数据:
$.ajax({ url: 'user.php', type: 'GET', dataType: 'json', // 修正拼写 success: function (data) { products = data; displayProductItems(products); displayMenuButtons(); }, error: function() { console.error('请求失败'); } });
内容的提问来源于stack exchange,提问作者Heezi
相关产品推荐
相关产品推荐

