JS客户端与Express服务器数据交互回调失效及请求格式问题
问题分析与解决方案
核心问题根源
你当前的代码存在两个关键逻辑错误:
$.post('/getDistance', a)和单独创建的res5XMLHttpRequest实例是完全独立的两个请求。服务器响应的是$.post发起的请求,但你监听的是res5的load事件,自然不会触发回调。- 改用
res5.send(a)时,既没有设置正确的请求头告知服务器数据格式,也没有对请求数据做序列化处理,导致Express无法解析req.body;同时load事件只要请求完成(无论服务器返回成功还是失败状态)就会触发,因此出现"不管服务器是否调用res.send都会触发"的问题。
方案一:保留$.post的修正方案
直接利用$.post的回调函数处理响应,删除无关的XMLHttpRequest代码:
客户端修正代码
function getDistance(doc) { theDistance = 0; var a = {reqID: doc, currentUser: currentUserData.Address}; // 给$.post绑定成功/失败回调 $.post('/getDistance', a) .done(function(response) { // 复用原onLoad5的处理逻辑 console.log('OFHDISHOIFDDSHOIFDHSOIFHDSIFSODFS') // jQuery会自动解析JSON格式的响应,无需手动JSON.parse var parsedResponse = response; console.log('here') var isError = parsedResponse['Error']; if(isError == "yes") { chats = []; displayErrorMessage("Error getting requests. Please contact us or try again soon."); return; } var dsm = parsedResponse['dsm']; distances.push(Number(dsm)); distanceObjects.push(new Distance(Number(dsm))); console.log("New Cycle Test Value w/: " + Number(requests.indexOf(currentDistancingRequest + 1))); beginDistanceRetrieval(requests.indexOf(currentDistancingRequest) + 1); }) .fail(function() { // 请求失败时触发错误提示 displayErrorMessage("Error getting requests. Please contact us or try again soon."); }); } // 删除以下无用代码: // var res5 = new XMLHttpRequest(); // var url5 = '/getDistance'; // res5.open('POST',url5,true); // res5.addEventListener('load',onLoad5); // res5.addEventListener('error',onError);
服务器端优化代码
用res.json()自动完成JSON序列化和响应头设置,替代手动JSON.stringify:
app.post('/getDistance', function(req, res) { console.log('THIS DOES LOG') var reqID = req.body.reqID; console.log(reqID) var currentUserAddress = req.body.currentUser; var destination; var dataToSend = {dsm: "10miles"}; res.json(dataToSend); // 自动设置Content-Type为application/json并序列化 })
方案二:改用原生XMLHttpRequest的正确方案
如果不想依赖jQuery,需正确设置请求头并序列化请求数据:
客户端修正代码
function getDistance(doc) { theDistance = 0; var a = {reqID: doc, currentUser: currentUserData.Address}; var res5 = new XMLHttpRequest(); var url5 = '/getDistance'; res5.open('POST', url5, true); // 设置请求头,告诉服务器数据格式为表单编码(与$.post默认格式一致) res5.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); res5.addEventListener('load', onLoad5); res5.addEventListener('error', onError); // 将对象序列化为表单格式字符串(如reqID=xxx¤tUser=xxx) var formData = Object.keys(a).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(a[key])}` ).join('&'); res5.send(formData); } function onLoad5() { // 先判断响应状态码是否正常 if (this.status >= 200 && this.status < 300) { console.log('OFHDISHOIFDDSHOIFDHSOIFHDSIFSODFS') var response = this.responseText; var parsedResponse = JSON.parse(response); console.log('here') var isError = parsedResponse['Error']; if(isError == "yes") { chats = []; displayErrorMessage("Error getting requests. Please contact us or try again soon."); return; } var dsm = parsedResponse['dsm']; distances.push(Number(dsm)); distanceObjects.push(new Distance(Number(dsm))); console.log("New Cycle Test Value w/: " + Number(requests.indexOf(currentDistancingRequest + 1))); beginDistanceRetrieval(requests.indexOf(currentDistancingRequest) + 1); } else { // 状态码异常时触发错误处理 onError(); } } function onError() { displayErrorMessage("Error getting requests. Please contact us or try again soon."); }
内容的提问来源于stack exchange,提问作者blueberrr
相关产品推荐
相关产品推荐

