自己写了一个登陆认证的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函数被调用了两次,不知道为什么,请大神指点


4 回复

从你提供的代码来看,有几个问题需要解决。首先,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');
});

解释

  1. 异步处理connection.query 是异步操作,因此我们将其放在 req.on('end') 事件中,确保在查询完成后才执行 judgement 函数。
  2. 请求体处理:对于 POST 请求,我们需要读取请求体中的参数。通过监听 'data''end' 事件来收集请求体,并使用 querystring.parse 将其解析为对象。
  3. 错误处理:在查询数据库时添加错误处理逻辑,以确保在发生错误时能够返回适当的响应。

这样修改后,你的 API 应该可以正确处理登录请求,并根据数据库查询结果返回相应的响应。


因为客户端会发送两个请求一个是浏览器自带favicon.ico请求,过滤一下就可以了!

我刚刚自己试了下 在请求判断中加入if(request.url != ‘/favicon.ico’){ //todo } 已经可以了,谢谢!

根据你提供的代码和调试信息,有几个问题需要解决:

  1. getResponse 函数被调用两次是因为你在一个异步操作(数据库查询)之后没有正确地处理结果。connection.query 是一个异步操作,你需要在回调函数中完成后续的处理逻辑。

  2. 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');
});

关键点解释

  1. 使用参数化查询:使用 ? 和数组来传递参数,防止 SQL 注入。
  2. 回调处理:将 judgement 逻辑放到 connection.query 的回调函数中,确保在查询完成后执行。
  3. 错误处理:添加错误处理逻辑,避免未捕获的错误导致程序崩溃。
  4. 响应状态码:为不同的情况设置合适的 HTTP 状态码。
回到顶部