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

Ajax结合PHP MySQL加载图片模态框数据报错问题排查

缩略图点击加载详情接口报错修复

问题描述

  • 需求:点击缩略图弹出大图,同时异步加载对应图片的详情内容展示在图片旁
  • 实现逻辑:点击缩略图时触发绑定函数,从DOM的dataset属性读取图片ID,将ID传入PHP接口查询MySQL数据库,返回对应描述内容渲染到模态框
  • 异常:原生JS、jQuery两个版本的实现均无法正常加载内容,页面返回PHP报错信息

运行时抛出的报错:

Warning: Undefined array key "datapass" in C:\xampp\htdocs\Project\modalTitle.php on line 3
Fatal error: Uncaught TypeError: mysqli_fetch_all(): Argument #1 ($result) must be of type mysqli_result,
bool given in C:\xampp\htdocs\Project\modalTitle.php:9 Stack trace: #0 
C:\xampp\htdocs\Project\modalTitle.php(9): mysqli_fetch_all(false, 1) #1 {main} thrown in 
C:\xampp\htdocs\Project\modalTitle.php on line 9

问题根因

  • 原生JS版本的XHR请求未拼接datapass参数,请求地址只有modalTitle.php,没有携带图片ID,PHP端读取不到$_GET['datapass']触发第一个警告
  • PHP端无入参校验逻辑,参数缺失时直接拼接到SQL语句,生成的SQL语法错误(SELECT description FROM content where timecode=),mysqli_query执行失败返回false,将布尔值传入mysqli_fetch_all触发第二个致命错误
  • 原PHP代码直接拼接用户传入参数到SQL语句,存在SQL注入风险
  • 前端无异常处理逻辑,接口报错时直接将错误信息渲染到页面

修复后代码

原生JS版本

function modalTitleLoad(e) {
  // 兼容点击缩略图内部子元素的场景,向上查找绑定data-id的DOM节点
  const target = e.target.closest('[data-id]');
  if (!target) return;
  const imgId = target.dataset.id;
  const xhr = new XMLHttpRequest();
  // GET请求参数拼接在URL后,使用encodeURIComponent处理特殊字符
  xhr.open('GET', `modalTitle.php?datapass=${encodeURIComponent(imgId)}`);
  xhr.onload = function () {
    const titleDom = document.querySelector('.modal__title');
    if (this.status !== 200) {
      titleDom.textContent = '加载失败,请重试';
      return;
    }
    try {
      const res = JSON.parse(this.response);
      titleDom.textContent = res.code === 0 ? (res.data.description || '暂无详情') : (res.msg || '加载失败');
    } catch (err) {
      titleDom.textContent = '数据解析失败';
    }
  };
  xhr.onerror = function () {
    document.querySelector('.modal__title').textContent = '网络异常,请检查连接';
  };
  xhr.send();
}

// 绑定点击事件示例:document.querySelectorAll('.thumbnail').forEach(item => item.addEventListener('click', modalTitleLoad))

jQuery版本

function modalData(e) {
  const target = e.target.closest('[data-id]');
  if (!target) return;
  const imgId = target.dataset.id;
  $.ajax({
    type: 'GET',
    url: 'modalTitle.php',
    dataType: 'json', // 自动解析JSON格式返回值
    data: { datapass: imgId },
    success: function (res) {
      $('.modal__title').text(res.code === 0 ? (res.data.description || '暂无详情') : (res.msg || '加载失败'));
    },
    error: function () {
      $('.modal__title').text('请求失败,请重试');
    }
  });
}

// 不要手动全局调用modalData(event),通过事件绑定自动传入事件对象
// 绑定示例:$('.thumbnail').on('click', modalData)

PHP接口版本

<?php
header('Content-Type: application/json; charset=utf-8');
// 统一返回结构
$res = ['code' => 1, 'msg' => '参数非法', 'data' => null];

// 入参校验
if (!isset($_GET['datapass']) || !trim($_GET['datapass'])) {
  echo json_encode($res);
  exit;
}
$imgId = trim($_GET['datapass']);

// 数据库连接校验
$conn = mysqli_connect('localhost', 'root', '', 'db');
if (!$conn) {
  $res['msg'] = '服务异常';
  echo json_encode($res);
  exit;
}
mysqli_set_charset($conn, 'utf8mb4');

// 预处理语句防SQL注入,若timecode是数字类型将bind_param的第一个参数's'改为'i'
$stmt = mysqli_prepare($conn, "SELECT description FROM content WHERE timecode = ?");
mysqli_stmt_bind_param($stmt, "s", $imgId);
mysqli_stmt_execute($stmt);
$queryRes = mysqli_stmt_get_result($stmt);

if (!$queryRes) {
  $res['msg'] = '查询失败';
  echo json_encode($res);
  exit;
}

$row = mysqli_fetch_assoc($queryRes);
if ($row) {
  $res['code'] = 0;
  $res['msg'] = 'success';
  $res['data'] = $row;
} else {
  $res['msg'] = '未查询到对应内容';
}

echo json_encode($res);

// 释放资源
mysqli_stmt_close($stmt);
mysqli_close($conn);
?>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:30:55