自己写了一个登陆认证的API,但是Nodejs程序一直调不对,路过的大神请指点下Nodejs相关问题
自己写了一个登陆认证的API,但是Nodejs程序一直调不对,路过的大神请指点下Nodejs相关问题
//loginauth.js var mysql = require(‘mysql’); var http = require(‘http’); var server= http.createServer(); var querystring = require(‘querystring’);
var connection = mysql.createConnection({ host: ‘localhost’, user: ‘root’, password: ‘’, database:‘main’, port: 3306 }); connection.connect();
//回应get方法的函数
len=0;//字符串长度定义
var getResponse = function(req, res){ res.writeHead(200, {‘Content-Type’: ‘text/plain’}); var name = require(‘url’).parse(req.url,true).query.userName//获取用户名字 var strname=JSON.stringify(name); console.log(name); var pwd=require(‘url’).parse(req.url,true).query.password //获取用户密码 var strpwd=JSON.stringify(pwd); console.log(pwd); var select=‘select * from user where stu_account=’+connection.escape(name)+ ‘and stu_pwd=’+connection.escape(pwd); //SQL查询语句 //var select=‘select * from user where stu_account=’+connection.escape(name)+ ‘and stu_pwd=’+connection.escape(pwd); //SQL查询语句 console.log(select);
connection.query(select,function(err1,res1){//查询结果并字符串化,得到字符串长度
if (err1) console.log(err1);
idstr=JSON.stringify(res1);
console.log(idstr);
len=idstr.length;
console.log(len);
});
}
//判断len的长度返回判断数据
var judgement=function(req,res){
if(len<3){
console.log(‘failed’);
res.end(‘failed’,‘utf8’);
}
else{
console.log(“success”);
res.end(‘success’,‘utf8’);
}
}
//request处理请求类别,对应相应的处理函数
var http = require(‘http’);
requestFunction = function (req, res){
req.setEncoding(‘utf8’);//请求编码
if (req.method == ‘GET’){
getResponse(req,res);
judgement(req,res);
console.log(“judgement exec1”);
}
else{
return 0;
}
console.log(“request exec1”);
}
//服务器运行的一些代码
server.on(‘request’,requestFunction);
server.listen(8080, “172.30.30.70”);
console.log(‘http start’);
node.js控制台调试信息: 031//账号 6934105ad50010b814c933314b1da6841431bc8b//密码 select * from user where stu_account='031’and stu_pwd=‘6934105ad50010b814c933314 b1da6841431bc8b’ failed judgement exec1 request exec1 [] 2 undefined undefined select * from user where stu_account=NULLand stu_pwd=NULL failed judgement exec1 request exec1 { [Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’stu_pwd=NULL’ at line 1] code: ‘ER_PARSE_ERROR’, errno: 1064, sqlState: ‘42000’, index: 0 } undefined
调试发现,getResponse函数被调用了两次,不知道为什么,请大神指点
从你提供的代码来看,有几个问题需要解决。首先,getResponse
函数中的 connection.query
是异步操作,这意味着在 connection.query
执行完成之前,judgement
函数就已经被执行了。其次,你需要确保正确地处理请求体(如果使用 POST 请求),并且在获取到数据库查询结果之后再进行判断。
以下是一个改进后的示例代码:
const http = require('http');
const url = require('url');
const querystring = require('querystring');
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'main',
port: 3306
});
connection.connect();
function getResponse(req, res) {
let body = [];
req.on('data', chunk => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
const params = querystring.parse(body);
const userName = params.userName;
const password = params.password;
console.log(userName);
console.log(password);
const select = `SELECT * FROM user WHERE stu_account=${connection.escape(userName)} AND stu_pwd=${connection.escape(password)}`;
console.log(select);
connection.query(select, (err, results) => {
if (err) {
console.error(err);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Internal Server Error');
return;
}
if (results.length > 0) {
console.log("success");
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('success');
} else {
console.log("failed");
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('failed');
}
});
});
}
const server = http.createServer((req, res) => {
req.setEncoding('utf8');
if (req.method === 'POST') {
getResponse(req, res);
} else {
res.writeHead(405, { 'Content-Type': 'text/plain' });
res.end('Method Not Allowed');
}
});
server.listen(8080, "172.30.30.70", () => {
console.log('HTTP server started on port 8080');
});
解释
- 异步处理:
connection.query
是异步操作,因此我们将其放在req.on('end')
事件中,确保在查询完成后才执行judgement
函数。 - 请求体处理:对于 POST 请求,我们需要读取请求体中的参数。通过监听
'data'
和'end'
事件来收集请求体,并使用querystring.parse
将其解析为对象。 - 错误处理:在查询数据库时添加错误处理逻辑,以确保在发生错误时能够返回适当的响应。
这样修改后,你的 API 应该可以正确处理登录请求,并根据数据库查询结果返回相应的响应。
因为客户端会发送两个请求一个是浏览器自带favicon.ico请求,过滤一下就可以了!
我刚刚自己试了下 在请求判断中加入if(request.url != ‘/favicon.ico’){ //todo } 已经可以了,谢谢!
根据你提供的代码和调试信息,有几个问题需要解决:
-
getResponse
函数被调用两次是因为你在一个异步操作(数据库查询)之后没有正确地处理结果。connection.query
是一个异步操作,你需要在回调函数中完成后续的处理逻辑。 -
judgement
函数不应该独立于getResponse
函数,而应该放在connection.query
的回调函数内部,确保在查询完成后进行判断。
以下是修改后的代码示例:
var mysql = require('mysql');
var http = require('http');
var querystring = require('querystring');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'main',
port: 3306
});
connection.connect();
var server = http.createServer((req, res) => {
req.setEncoding('utf8');
if (req.method === 'GET') {
var urlParts = require('url').parse(req.url, true);
var name = urlParts.query.userName;
var pwd = urlParts.query.password;
console.log(`Username: ${name}, Password: ${pwd}`);
var select = 'SELECT * FROM user WHERE stu_account=? AND stu_pwd=?';
connection.query(select, [name, pwd], (err, results) => {
if (err) {
console.error(err);
res.writeHead(500, {'Content-Type': 'text/plain'});
res.end('Internal Server Error');
return;
}
console.log(JSON.stringify(results));
if (results.length > 0) {
console.log("success");
res.end('success', 'utf8');
} else {
console.log("failed");
res.end('failed', 'utf8');
}
});
} else {
res.writeHead(405, {'Content-Type': 'text/plain'});
res.end('Method Not Allowed');
}
});
server.listen(8080, "172.30.30.70", () => {
console.log('HTTP server started');
});
关键点解释
- 使用参数化查询:使用
?
和数组来传递参数,防止 SQL 注入。 - 回调处理:将
judgement
逻辑放到connection.query
的回调函数中,确保在查询完成后执行。 - 错误处理:添加错误处理逻辑,避免未捕获的错误导致程序崩溃。
- 响应状态码:为不同的情况设置合适的 HTTP 状态码。