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

PHP可获取数据库数据,但Ajax无法传数据至JavaScript数组问题

问题分析与解决方案

你的核心问题出在AJAX异步逻辑执行顺序、变量作用域和this指向错误上,导致无法拿到PHP返回的产品数据并完成页面渲染。以下是具体问题点和修复方案:

问题点拆解

  1. 变量作用域限制:原生AJAX回调里的products是局部变量,外部的展示函数根本访问不到;
  2. 箭头函数的this指向错误:xhr.onload = () => {}用了箭头函数,this不会指向XMLHttpRequest实例,导致状态判断失效,JSON解析代码从未执行;
  3. 异步逻辑顺序错误:页面加载完成后直接调用渲染函数,但此时AJAX请求还没完成,products变量不存在;
  4. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:37:17