NodeJS MongoDB聊天机器人Postman请求无限加载无响应问题
问题:NodeJS+MongoDB聊天机器人接口无响应,CRUD执行成功但Postman无限等待
我开发了一个基于NodeJS和MongoDB的聊天机器人应用,完整代码如下:
const express = require('express'); const app = express(); const MongoClient = require('mongodb').MongoClient; const assert = require('assert'); const bodyParser = require('body-parser'); const dbName = "chatbotdb"; const jsonParser = bodyParser.json(); const urlencodedParser = bodyParser.urlencoded({extended: false}); app.use(jsonParser); app.use(urlencodedParser); const MongoConnection = (callback) =>{ //creating connection to MongoDB database with connect() method which returns a promise MongoClient.connect('mongodb://localhost:27017/chatbotdb') //pass the DB along with connection-URL .then(client=>{ console.log("Connected"); db = client.db(); //fetch DB callback(); }) .catch(err=>{ console.log(err); }); } app.post('/insert', urlencodedParser, function(req, res){ let objJson = {}; if(req.body.code_user) objJson.code_user = req.body.code_user; else objJson.code_user = 0; if(req.body.code_session) objJson.code_session = req.body.code_session; else objJson.code_session = 0; if(req.body.code_current) objJson.code_current = req.body.code_current; else objJson.code_current = cod(); if(req.body.code_relation) objJson.code_relation = req.body.code_relation; else objJson.code_relation = 0; if(req.body.code_before) objJson.code_before = req.body.code_before; else objJson.code_before = 0; if(req.body.input) objJson.input = req.body.input; else objJson.input = ''; if(req.body.output) objJson.output = req.body.output; else objJson.output ='Desculpe, mas não entendi'; insertData(objJson, function(result){ res.send(result); }) }); function cod(){ const data = new Date(); const ano = data.getFullYear(); const mes = data.getMonth(); const dia = data.getDate(); const hora = data.getHours(); const minuto = data.getMinutes(); const segundo = data.getSeconds(); const milisegundos = data.getMilliseconds(); const result = parseInt(Number(ano+''+mes+''+dia+''+hora+''+minuto+''+segundo+''+milisegundos)/2); return result; } app.post('/update', urlencodedParser, function(req, res){ let objJson = {}; if(req.body.code_user) objJson.code_user = req.body.code_user; if(req.body.code_session) objJson.code_session = req.body.code_session; if(req.body.code_current) objJson.code_current = req.body.code_current; if(req.body.code_relation) objJson.code_relation = req.body.code_relation; if(req.body.code_before) objJson.code_before = req.body.code_before; if(req.body.input) objJson.input = req.body.input; if(req.body.output) objJson.output = req.body.output; updateData(objJson, function(result){ res.send(result); }) }); app.post('/delete', urlencodedParser, function(req, res){ let objJson = {}; if(req.body.code_user) objJson.code_user = req.body.code_user; if(req.body.code_session) objJson.code_session = req.body.code_session; if(req.body.code_current) objJson.code_current = req.body.code_current; if(req.body.code_relation) objJson.code_relation = req.body.code_relation; if(req.body.code_before) objJson.code_before = req.body.code_before; if(req.body.input) objJson.input = req.body.input; if(req.body.output) objJson.output = req.body.output; deleteData(objJson, function(result){ res.send(result); }); }); app.post('/find', urlencodedParser, function(req, res){ let objJson = {}; if(req.body.code_user) objJson.code_user = req.body.code_user; if(req.body.code_session) objJson.code_session = req.body.code_session; if(req.body.code_current) objJson.code_current = req.body.code_current; if(req.body.code_relation) objJson.code_relation = req.body.code_relation; if(req.body.code_before) objJson.code_before = req.body.code_before; if(req.body.input) objJson.input = req.body.input; if(req.body.output) objJson.output = req.body.output; findData(objJson, function(result){ res.send(result); }); }); const insertData = function(objJson, callback){ const collection = db.collection('chatbot'); collection.insertOne(objJson, function(err, result){ assert.equal(null,err); callback(result); }); } const updateData = function(objJson, callback){ const collection = db.collection('chatbot'); const code_current = objJson.code_current; collection.updateOne({code_current: code_current}, {$set: objJson} , function(err, result){ assert.equal(null,err); callback(result); }); } const deleteData = function(objJson, callback){ const collection = db.collection('chatbot'); collection.deleteOne(objJson, function(err, result){ assert.equal(null,err); callback(result); }); } const findData = function(objJson, callback){ const collection = db.collection('chatbot'); collection.find(objJson).toArray(function(err, result){ assert.equal(null,err); callback(result); }); } MongoConnection(()=>{ app.listen(3000, () => { console.log(`Database running & Listening on port: 3000`); }) }) app.get('/question', urlencodedParser, function(req, res){ let objJson = {}; if(req.query.code_user) objJson.code_user = Number(req.query.code_user); else objJson.code_user = 0; if(req.query.code_session) objJson.code_session = Number(req.query.code_session); else objJson.code_session = 0; if(req.query.code_before) objJson.code_before = Number(req.query.code_before); else objJson.code_before = 0; if(req.query.input) objJson.input = req.query.input; else objJson.input = ''; questionData(objJson, function(result){ res.send(result); }); }); const questionData = function(objJson, callback){ const collection = db.collection('chatbot'); collection.find(objJson).toArray(function(err, result){ assert.equal(null,err); if(result.length<=0){ collection.find({code_user:objJson.code_user}).toArray(function(err, result){ assert.equal(null,err); result = nlp(objJson.input, result); callback(result); }); } else callback(result); }); } const nlp = function(question, array){ let originalQuestion = question.toString().trim(); let findInput = 0; let findIndex = 0; for(let i=0; i<array.length; i++){ question = question.toString().trim(); let input = array[i].input.toString().trim() if(input.length<=0) input = array[i].output.toString.trim(); question = question.normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase(); input = input.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); question = question.replace(/[^a-zA-Z0-9\s]/g, ''); input = input.replace(/[^a-zA-Z0-9\s]/g); let tokenizationQuestion = question.split(' '); let tokenizationInput = input.split(' '); tokenizationQuestion = tokenizationQuestion.map(function(e){ if(e.length>3) return e.substr(0, e.length-3); else return e; }); tokenizationInput = tokenizationInput.map(function(e){ if(e.length>3) return e.substr(0, e.length-3); else return e; }); let words = 0; for(let x=0; x<tokenizationQuestion.length; x++){ if(tokenizationInput.indexOf(tokenizationQuestion[x])>=0) words++; } if(words>findInput){ findInput = words; findIndex = i; } } if(findInput>0) return[{ "_id": array[findIndex]._id, "code_user":array[findIndex].code_user, "code_session": array[findIndex].code_session, "code_current": array[findIndex].code_current, "code_relation": array[findIndex].code_relation, "code_before": array[findIndex].code_before, "input": originalQuestion, "output": array[findIndex].output }]; else return [{ "_id": "0", "code_user":array[findIndex].code_user, "code_session": array[findIndex].code_session, "code_current": array[findIndex].code_current, "code_relation": array[findIndex].code_relation, "code_before": array[findIndex].code_before, "input": originalQuestion, "output": "Desculpe, mas não sei responder." }]; }
使用Postman发送POST和GET请求时,CRUD操作实际已成功执行(集合数据已更新、删除或插入),但Postman始终无限显示“Sending request...”,无法获取服务器响应,导致无法使用/find接口和GET方法查询特定数据。
问题根源及修复步骤
1. 修复未声明的全局db变量
代码中db = client.db();属于隐式全局变量,可能导致不可预期的作用域问题,在代码顶部显式声明:
const express = require('express'); const app = express(); const MongoClient = require('mongodb').MongoClient; const assert = require('assert'); const bodyParser = require('body-parser'); const dbName = "chatbotdb"; let db; // 显式声明全局db变量
2. 修复nlp函数中的语法与逻辑错误
input = array[i].output.toString.trim();缺少方法调用括号,改为input = array[i].output.toString().trim();input = input.replace(/[^a-zA-Z0-9\s]/g);缺少替换目标值,改为input.replace(/[^a-zA-Z0-9\s]/g, '')- 增加数组为空的判断,避免
array[findIndex]访问undefined属性:
const nlp = function(question, array){ let originalQuestion = question.toString().trim(); let findInput = 0; let findIndex = 0; // 先判断数组是否为空,直接返回默认响应 if(array.length === 0){ return [{ "_id": "0", "code_user": 0, "code_session": 0, "code_current": 0, "code_relation": 0, "code_before": 0, "input": originalQuestion, "output": "Desculpe, mas não sei responder." }]; } for(let i=0; i<array.length; i++){ question = question.toString().trim(); let input = array[i].input.toString().trim() if(input.length<=0) input = array[i].output.toString().trim(); question = question.normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase(); input = input.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); question = question.replace(/[^a-zA-Z0-9\s]/g, ''); input = input.replace(/[^a-zA-Z0-9\s]/g, ''); let tokenizationQuestion = question.split(' '); let tokenizationInput = input.split(' '); tokenizationQuestion = tokenizationQuestion.map(function(e){ if(e.length>3) return e.substr(0, e.length-3); else return e; }); tokenizationInput = tokenizationInput.map(function(e){ if(e.length>3) return e.substr(0, e.length-3); else return e; }); let words = 0; for(let x=0; x<tokenizationQuestion.length; x++){ if(tokenizationInput.indexOf(tokenizationQuestion[x])>=0) words++; } if(words>findInput){ findInput = words; findIndex = i; } } if(findInput>0) return[{ "_id": array[findIndex]._id, "code_user":array[findIndex].code_user, "code_session": array[findIndex].code_session, "code_current": array[findIndex].code_current, "code_relation": array[findIndex].code_relation, "code_before": array[findIndex].code_before, "input": originalQuestion, "output": array[findIndex].output }]; else return [{ "_id": "0", "code_user":array[findIndex].code_user, "code_session": array[findIndex].code_session, "code_current": array[findIndex].code_current, "code_relation": array[findIndex].code_relation, "code_before": array[findIndex].code_before, "input": originalQuestion, "output": "Desculpe, mas não sei responder." }]; }
3. 替换assert为错误捕获逻辑
assert.equal(null,err)会直接抛出错误,导致请求挂起,改为在回调中处理错误并返回响应:
// 以insertData为例,其他数据库操作函数同理修改 const insertData = function(objJson, callback){ const collection = db.collection('chatbot'); collection.insertOne(objJson, function(err, result){ if(err){ console.error(err); return callback({error: err.message}); } callback(result); }); }
4. 移除GET请求中的urlencodedParser
GET请求没有请求体,无需使用urlencodedParser中间件:
app.get('/question', function(req, res){ // 原有逻辑保留 });
验证修复
修改后重启服务,用Postman测试所有接口:
- CRUD操作完成后会正常返回响应,不再无限等待
/find和/question接口能正确返回查询结果或错误信息
内容的提问来源于stack exchange,提问作者Mind full of blanks
相关产品推荐
相关产品推荐

