在开始学nodejs时,一般我们就是直接
var http = require("http");
var fs = require('fs')
var url = require('url')
var querystring = require('querystring')
var mysql = require('mysql')
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'crashcourse'
})
connection.connect(function(err) {
if(err) {
console.log('数据库连接失败')
}
console.log('数据库连接成功')
})
http.createServer(function(req,res){
const pathname = req.url
if(pathname === '/') {
fs.readFile('../page/index.html','utf-8',function(err,data) {
if(err) {
throw err
}
res.writeHead(200,{"Content-type":"text/html"});
res.write(data)
res.end()
})
}else if(pathname === '/login') {
var body = ''
req.on('data',function(chunk) {
body += chunk
})
req.on('end',function() {
body = querystring.parse(body) //该方法会把一个 URL 查询字符串 str 解析成一个键值对的集合。
const sql = 'SELECT * FROM users WHERE username="'+ body.username +'"AND password="'+ body.password+'";'
connection.query(sql,function(err,results) {
if(err) {
throw err
}
if(results.length >= 1) {
const date = new Date().getTime() + 1000
res.writeHead(200,{"Content-type":"text/plain;charset=utf-8","Set-Cookie":"username="+ body.username+""});
res.write('登陆成功')
res.end()
}else {
res.writeHead(301,{"Content-type":"text/html;charset=utf8"});
res.write('<p>登陆失败,用户名或密码错误<a href="/">返回</a></p>')
res.end()
}
})
// if(body.username ==='admin@qq.com' && body.password === '123') {
// res.writeHead(200,{"Content-type":"text/plain;charset=utf-8"});
// res.write('登陆成功')
// res.end()
// }else {
// res.writeHead(301,{"Content-type":"text/plain;charset=utf-8"});
// res.write('用户名密码错误')
// res.end()
// }
})
}else if(pathname === '/register') {
if(req.method === 'POST') {
var body = ''
req.on('data',function(chunk) {
body+=chunk
})
req.on('end',function() {
body = querystring.parse(body)
if(body.username !== '' && body.password !== '') {
//方法一 sql语句拼接变量 ?为占位符
// var addsqlparams = [body.username,body.password];
// var sql = 'INSERT INTO users VALUES(NULL,?,?);'
// connection.query(sql, addsqlparams ,function(err,results) {
// connection.destroy()
// res.writeHead(200,{'content-type': 'text/html;charset=utf8'})
// res.write('<p><span>注册成功!</span><a href="/">前往登陆</a></p>')
// res.end()
// if(err) throw err
// })
//方法二
connection.query('INSERT INTO users VALUES(NULL,"'+ body.username +'","'+ body.password +'")' ,function(err,results) {
connection.destroy()
res.writeHead(200,{'content-type': 'text/html;charset=utf8'})
res.write('<p><span>注册成功!</span><a href="/">前往登陆</a></p>')
res.end()
if(err) throw err
})
}
})
}else {
res.writeHead(200,{"Content-type":"text/html"});
fs.readFile('../page/register.html',function(err,data) {
if(err) {
throw err
}
res.write(data)
res.end()
})
}
}
}).listen(8080);
比如上面这段代码,就是实现一个登陆注册的简单功能,虽然功能是正常实现了,但是代码结构很乱,没有路由来管理请求
我们应该有
- server 服务器
- route 路由
- requestHandlers 请求对应的处理程序
- model 数据库处理
- index 入口文件
接下来来改造上面的代码
> server.js
var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
//依赖注入
route(handle, pathname, response,request);
}
http.createServer(onRequest).listen(8080);
console.log("Server has started.");
}
exports.start = start;
router.js
function route(handle, pathname, response, request) {
console.log("About to route a request for " + pathname);
if (typeof handle[pathname] === 'function') {
//将response也作为参数传递,以非阻塞操作进行请求响应
return handle[pathname](response,request);
} else {
console.log("No request handler found for " + pathname);
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not found");
response.end();
}
}
exports.route = route;
requestHandlers
var exec = require("child_process").exec;
var user = require('./model/user');
var fs = require('fs');
var querystring = require('querystring')
function start(response, request) {
console.log("Request handler 'start' was called.");
// function sleep(milliSeconds) {
// var startTime = new Date().getTime();
// while (new Date().getTime() < startTime + milliSeconds);
// }
//
// sleep(10000);
// var content = "empty";
// child_process。之所以用它,是为了实现一个既简单又实用的非阻塞操作:exec()
// exec("ls -lah", function (error, stdout, stderr) {
// content = stdout; //这里是异步操作
// });
//
// return content
// exec("find /",
// { timeout: 10000, maxBuffer: 20000*1024 },
// function (error, stdout, stderr) {
// response.writeHead(200, {"Content-Type": "text/plain"});
// response.write(stdout);
// response.end();
// });
if (request.method === 'GET') {
fs.readFile('../page/index.html', 'utf-8', function(err, data) {
if (err) {
throw err
}
response.writeHead(200, {
"Content-type": "text/html"
});
response.write(data)
response.end()
})
} else if (request.method === 'POST') {
var body = ''
request.on('data', function(chunk) {
body += chunk
})
request.on('end', function() {
body = querystring.parse(body)
const sql = 'SELECT * FROM users WHERE username="' + body.username + '"AND password="' + body.password + '";'
user.query(sql, function(results) {
if (results.length >= 1) {
const date = new Date().getTime() + 1000
response.writeHead(200, {
"Content-type": "text/plain;charset=utf-8",
"Set-Cookie": "username=" + body.username + ""
});
response.write('登陆成功')
response.end()
} else {
response.writeHead(301, {
"Content-type": "text/html;charset=utf8"
});
response.write('<p>登陆失败,用户名或密码错误<a href="/">返回</a></p>')
response.end()
}
})
})
}
}
function upload(response) {
///upload URL居然也花了10秒,而它在对应的请求处理程序中并没有类似于sleep()这样的操作!
// console.log("Request handler 'upload' was called.");
// return "Hello Upload";
console.log("Request handler 'upload' was called.");
response.writeHead(200, {
"Content-Type": "text/plain"
});
response.write("Hello Upload");
response.end();
}
exports.start = start;
exports.upload = upload;
model.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'crashcourse'
})
connection.connect(function(err) {
if (err) {
console.log('数据库连接失败')
}
console.log('数据库连接成功')
})
function query(sql, callback) {
connection.query(sql, function(err, results) {
if (err) throw err
callback(results)
})
}
exports.query = query
index.js
var server = require('./server')
var router = require('./router')
var requestHandlers = require('./requestHandlers')
var handle = {}
handle["/"] = requestHandlers.start
handle["/start"] = requestHandlers.start
handle["/upload"] = requestHandlers.upload
server.start(router.route,handle)
在index.js文件中可以看到,将router路由文件和请求处理requestHandlers分别注入到server中,这里新建了一个handle对象,Key值为对应请求的url路径,value为我们在requestHandlers中定义的函数,根据路径的不同分别去调用不同的函数来响应这个请求。
server.js只负责创建服务器,请求分发处理都交给路由来统一管理
在router.js中`typeof handle[pathname] === 'function'` 如果条件成立,代表当前请求有对应的函数来处理。
在server.js将request和response参数传递到requestHandler中,因为要用到这两个对象,比如这里根据req的method如果是GET直接就返回一个html表单界面,是POST代表正在登录。
model里就是随便简单的封装了一下,也可以直接把sql封装到model中,调用的时候不直接写sql语句,而且根据传的值在model中生成,对于一些异步处理可以直接采用Promise等一些方法来处理,以及可以用数据库连接池来处理连接。
可以去参考一下nodejs入门这本书,以后开发的时候肯定直接就用express或koa这种框架来写,但是刚学nodejs时这种简单的架构还是有必要了解一下,对以后学习nodejs相关的web框架肯定是有帮助的。
`
来源:CSDN
作者:sinat_29289673
链接:https://blog.csdn.net/sinat_29289673/article/details/85010968