Node.js开发:输入user_id触发Ajax拉取MySQL数据回填表单却返回整个ejs页面
问题核心原因
当前的服务端路由没有区分「普通页面访问请求」和Ajax异步数据请求,不管收到什么指向根路径/的GET请求,都会直接执行res.render("form")返回完整的EJS渲染页面,这就是前端拿到整段表单代码而非JSON数据的根本原因。
需要调整的核心点
- 拆分路由职责:把页面渲染逻辑和Ajax接口逻辑完全分开,不要把两类逻辑塞在同一个路由里
- 修正服务端代码的隐性bug:原来的代码存在变量作用域问题、循环取值覆盖问题、异常场景未处理的问题
- 修正前端请求地址:让Ajax请求指向专门的接口,不要和首页地址复用
改造后可运行的代码
服务端 Server.js 调整
// 根路径路由:仅负责渲染表单页面,不处理数据库查询逻辑 app.get('/', function (req, res) { res.render("form"); }); // 独立的用户信息查询接口:专门给Ajax请求返回JSON数据 app.get('/get-user-info', function (req, res) { const userid = req.query.user_id; // 入参为空直接返回空数据 if(!userid) { return res.json({ first_name: "", last_name: "" }); } // 执行数据库查询,只取需要的字段加LIMIT 1减少性能损耗 connection.query("SELECT first_name, last_name FROM userdata WHERE user_id = ? LIMIT 1", [userid], function (err, results) { if(err) { console.error("数据库查询异常:", err); return res.status(500).json({ first_name: "", last_name: "" }); } // 无匹配用户时返回空值,前端自动清空输入框 if(results.length === 0) { return res.json({ first_name: "", last_name: "" }); } // 匹配到用户直接返回结构化JSON,不做页面渲染 const user = results[0]; res.json({ first_name: user.first_name, last_name: user.last_name }); }); });
前端 ajax.js 调整
替换Ajax请求的目标地址为独立接口,调整取值逻辑适配返回的JSON结构:
function GetDetail(str) { if (str.length == 0) { document.getElementById("first_name").value = ""; document.getElementById("last_name").value = ""; return; } else { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { // 此时响应内容为纯JSON,不再是完整的EJS页面代码 var userInfo = JSON.parse(this.responseText); document.getElementById("first_name").value = userInfo.first_name; document.getElementById("last_name").value = userInfo.last_name; } } // 指向独立的接口地址,同时对输入值做编码避免特殊字符触发请求异常 xmlhttp.open("GET", "/get-user-info?user_id=" + encodeURIComponent(str), true); xmlhttp.send(); } }
逻辑说明
改造后:
- 用户通过浏览器直接访问首页时,走
/路由接收渲染好的表单页面,正常显示 - 输入user_id触发Ajax时,请求会命中独立的
/get-user-info接口,服务端直接返回结构化的姓名数据,不再返回页面代码,前端可以正常解析后回填到对应输入框。
注:原代码的变量作用域问题:之前写在查询回调内部的
a、b变量,在回调外部执行data.push(a,b)时,一旦查询出错或无匹配结果,会直接抛出「变量未定义」的报错,拆分接口逻辑后这类问题会被一并修复。
内容的提问来源于stack exchange,提问作者Mata28
相关产品推荐
相关产品推荐

