为何PHP输出后innerHTML未变化?排查AJAX交互异常
问题排查:AJAX请求后innerHTML未更新(触发不稳定)
开发流程与代码
- 步骤1:HTML输入框
<form method> <input name="filmslike" id="input"> </form>
- 步骤2:JavaScript发起AJAX请求
let div2Change = document.getElementById("div2Change"); let input = document.getElementById("input"); input.addEventListener("change", getTable); function getTable(){ let ajax = new XMLHttpRequest(); ajax.open("GET", "filmslike.php"); ajax.send(); ajax.onreadystatechange = function(){ if (ajax.readyState == 4 && ajax.status == 200){ alert("in if"); array = JSON.parse(ajax.responseText); str = "<table class='table'>"; for (i = 0; i < array.length; i++){ str += "<tr><td>" + array[i] + "</td></tr>"; } str += "<table>"; div2Change.innerHTML = str; } } }
- 步骤3:PHP处理请求
require "DatabaseAdaptor.php"; // 引入DatabaseAdaptor类 $theDBA = new DatabaseAdaptor(); // 实例化数据库适配器对象 $moviesLike = $_GET['filmslike']; $array = $theDBA->getAllMoviesLike($moviesLike); echo json_encode($array);
- 步骤4:数据库查询函数
public function getAllMoviesLike($part) { $stmt = $this->DB->prepare("SELECT * FROM movies WHERE name like '%" . $part . "%'"); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); }
遇到的问题
innerHTML未发生变化,alert提示已进入判断语句但触发不稳定,改用POST请求也无效。
问题根源与修复方案
1. GET请求未携带参数(核心问题)
JavaScript的AJAX请求没有把输入框的filmslike参数拼接到URL中,导致PHP的$_GET['filmslike']获取不到值,数据库查询无结果,返回空数组,最终innerHTML没有可渲染的内容。
修复后JS代码(GET方式):
function getTable(){ let ajax = new XMLHttpRequest(); // 拼接参数并编码,防止特殊字符导致请求异常 const params = "filmslike=" + encodeURIComponent(input.value); ajax.open("GET", "filmslike.php?" + params); ajax.send(); ajax.onreadystatechange = function(){ if (ajax.readyState == 4 && ajax.status == 200){ // 后续逻辑 } } }
2. 事件监听选择不当导致触发不稳定
change事件仅在输入框失去焦点且内容改变时触发,用户输入过程中不会实时响应,导致触发时机不可控。建议改用input事件,输入内容变化时立即触发。
修复事件监听:
input.addEventListener("input", getTable);
3. SQL语句拼接错误+注入风险
数据库函数中直接拼接$part到SQL语句,存在严重SQL注入风险,若$part包含特殊字符(如单引号),还会导致SQL语法错误,查询失败。必须使用PDO预编译占位符。
修复后数据库函数:
public function getAllMoviesLike($part) { // 使用占位符自动处理转义,避免注入和语法错误 $stmt = $this->DB->prepare("SELECT * FROM movies WHERE name LIKE CONCAT('%', :part, '%')"); $stmt->bindParam(':part', $part); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); }
4. 变量未声明导致全局污染
array、str、i未用let/var声明,会变成全局变量,可能被其他代码意外覆盖,导致逻辑异常。
修复变量声明:
function getTable(){ let ajax = new XMLHttpRequest(); const params = "filmslike=" + encodeURIComponent(input.value); ajax.open("GET", "filmslike.php?" + params); ajax.send(); ajax.onreadystatechange = function(){ if (ajax.readyState == 4 && ajax.status == 200){ alert("in if"); // 声明局部变量 const array = JSON.parse(ajax.responseText); let str = "<table class='table'>"; // 循环变量i也要声明为局部变量 for (let i = 0; i < array.length; i++){ // 注意:array[i]是对象,需取对应字段(如name) str += "<tr><td>" + array[i].name + "</td></tr>"; } // 修正闭合标签为</table> str += "</table>"; div2Change.innerHTML = str; } } }
5. HTML标签闭合错误
代码中最后拼接的是<table>而非</table>,导致HTML结构无效,浏览器无法正确渲染表格。
6. 缺失错误处理
未处理AJAX请求失败的情况(如readyState==4但status!=200),无法排查请求是否真的成功返回数据。建议添加错误日志:
ajax.onreadystatechange = function(){ if (ajax.readyState == 4){ if(ajax.status == 200){ // 成功逻辑 } else { console.error("请求失败,状态码:", ajax.status); console.error("响应内容:", ajax.responseText); } } }
内容的提问来源于stack exchange,提问作者Morgan
相关产品推荐
相关产品推荐

