nodejs 用http模块搭建的服务器的路由,以及路由代码的重构过程

我们打开浏览器浏览网页时,点击上面不同的模块,地址栏中的路由会发生相应的变化,从而,浏览器向服务器发起请求的内容也会发生改变,那么服务端,是如何来做的呢?

服务端也是,通过路由来做出不同的响应的,我们已经知道,服务器对象的参数有request,和response两个参数。request里就携带了,浏览器请求所携带的值。

request.url返回的是浏览器中路由的值

我们可以根据这个值来判断,服务器需要返回给浏览器什么内容,

下面来看一下server.js的代码:

var http = require("http");
var fs = require("fs"); var startServer = function(){
var onRequest = function(request,response){
console.log("request received"+request.url);
if(request.url==="/"||request.url==="/home"){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/index.html","utf8").pipe(response);
}else if(request.url==="/review"){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/review.html","utf8").pipe(response);
}else if(request.url==="/api"){
response.writeHead(200,{"Content-Type":"application/json"});
var jsonObj={name:"lili",job:"coder",age:18};
response.end(JSON.stringify(jsonObj));
}else{
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/404.html","utf8").pipe(response);
} } var server = http.createServer(onRequest);
//最后让服务器监听一个端口
server.listen(3000,"127.0.0.1");//还可以加第二个参数 127.0.0.1代表的是本地 console.log("server started on localhost port 3000");//加一个服务器启动起来的提示
} module.exports.startServer=startServer;

上面server.js中,根据不同的路由,让服务器返回给浏览器不同的内容,当找不到内容时,返回一个404页面

把server.js引入到app.js中

var server = require("./server");

server.startServer();

执行node app

在浏览器中 localhost:3000

后面跟上不同的路由,会显示不同的页面,当匹配不到路由时,会显示404页面!!!

路由重构过程

上面的代码又显的有些臃肿,需要来重构一下,怎么来重构呢?页面中许多路由路径,还有if判断显得有些臃肿,所以就重构它:

先从server.js开始,我们可以将这些if else判断语句注释掉,用一个函数代替

var http = require("http");
var fs = require("fs"); var startServer = function(route){
var onRequest = function(request,response){
console.log("request received"+request.url);
route(request.url);
// if(request.url==="/"||request.url==="/home"){
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/index.html","utf8").pipe(response);
// }else if(request.url==="/review"){
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/review.html","utf8").pipe(response);
// }else if(request.url==="/api"){
// response.writeHead(200,{"Content-Type":"application/json"});
// var jsonObj={name:"lili",job:"coder",age:18};
// response.end(JSON.stringify(jsonObj));
// }else{
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/404.html","utf8").pipe(response);
// } } var server = http.createServer(onRequest);
//最后让服务器监听一个端口
server.listen(3000,"127.0.0.1");//还可以加第二个参数 127.0.0.1代表的是本地 console.log("server started on localhost port 3000");//加一个服务器启动起来的提示
} module.exports.startServer=startServer;

那么响应的app.js中startServer函数也要传进去对应的参数

var server = require("./server");
var router = require("./router"); server.startServer(router.route);

那么app.js中传给startServer函数的route,从哪来呢?

我们重新建立一个模块,叫router.js,它里面应该导出一个route函数

route需要有一个request.url参数

如下:

function route(pathname){
console.log("Routing request for"+pathname);
} module.exports.route=route;

上面route函数的pathname参数是在server.js里调用这个函数时传进去的,而api调用startServer时,传进去的是route函数本身,并不需要传参数。

做完上面的,服务器的请求,就到route.js中了,我们需要在route.js中对服务器请求做一些响应,当然如果直接在route.js中把一些if else写进去,还是比较乱,没多大意义,我们可以再重新建立一个模块:handler.js来写这些响应代码:

重构的目的肯定是想,让代码更整洁,更“智能化”,所谓的智能化,就是你只需要改变一小点地方,代码会把相应的改变,帮自己改变,不用自己去改变更多的代码。在代码中的体现,就是封装方法,传入不一样的参数,这个方法做出不一样的操作。那么,在现在的路由中,改变的是request.url,我们需要封装一个方法,根据request.url的不同,而做出对应的响应。下面的handler.js里面,盛放的是一些,对应的函数方法。

handler.js:

function home(){
console.log("Executing 'home' handler");
} function review(){
console.log("Executing 'review' handler");
} function api_records(){
console.log("Executing 'api_records' handler");
} module.exports={
home,
review,
api_records
}

现在方法有了,需要与request.url发生对应关系,我们打算把这些对应关系放在api.js中:

api.js:

var server = require("./server");
var router = require("./router");
var handler = require("./handler"); var handle = {}; handle["/"]=handler.home;
handle["/home"]=handler.home;
handle["/review"]=handler.review;
handle["/api_records"]=handler.api_records; server.startServer(router.route,handle);

我们把路径与方法的对应关系,写在了一个handle对象中,然后传给了startServer方法内

那么,stratServer方法需要作出响应更改:

server.js:

var http = require("http");
var fs = require("fs"); var startServer = function(route,handle){
var onRequest = function(request,response){
console.log("request received"+request.url);
route(handle,request.url);
// if(request.url==="/"||request.url==="/home"){
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/index.html","utf8").pipe(response);
// }else if(request.url==="/review"){
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/review.html","utf8").pipe(response);
// }else if(request.url==="/api"){
// response.writeHead(200,{"Content-Type":"application/json"});
// var jsonObj={name:"lili",job:"coder",age:18};
// response.end(JSON.stringify(jsonObj));
// }else{
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/404.html","utf8").pipe(response);
// } } var server = http.createServer(onRequest);
//最后让服务器监听一个端口
server.listen(3000,"127.0.0.1");//还可以加第二个参数 127.0.0.1代表的是本地 console.log("server started on localhost port 3000");//加一个服务器启动起来的提示
} module.exports.startServer=startServer;

我们把handle对象传给了stratServer方法,然后又传给了,route方法,那么route方法,需要更改:

route.js:

function route(handle,pathname){
console.log("Routing request for"+pathname);
if(typeof handle[pathname] === 'function'){
handle[pathname]();
}else{
console.log("No handle for" + pathname);
}
} module.exports.route=route;

route方法内,判断当前路径对应的值是否是一个函数,是的话,执行这个函数,不是的话,后面处理,应该是跳转404页面,到后面处理

下一步,我们需要让handle方法做出相应,也就是响应给页面对应的内容,那么,我们就需要用到response对象,我们可以在stratServer中传给route方法:

var http = require("http");
var fs = require("fs"); var startServer = function(route,handle){
var onRequest = function(request,response){
console.log("request received"+request.url);
route(handle,request.url,response);
// if(request.url==="/"||request.url==="/home"){
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/index.html","utf8").pipe(response);
// }else if(request.url==="/review"){
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/review.html","utf8").pipe(response);
// }else if(request.url==="/api"){
// response.writeHead(200,{"Content-Type":"application/json"});
// var jsonObj={name:"lili",job:"coder",age:18};
// response.end(JSON.stringify(jsonObj));
// }else{
// response.writeHead(200,{"Content-Type":"text/html"});
// fs.createReadStream(__dirname+"/404.html","utf8").pipe(response);
// } } var server = http.createServer(onRequest);
//最后让服务器监听一个端口
server.listen(3000,"127.0.0.1");//还可以加第二个参数 127.0.0.1代表的是本地 console.log("server started on localhost port 3000");//加一个服务器启动起来的提示
} module.exports.startServer=startServer;

在router.js中也要穿进去:再传给handle方法:

function route(handle,pathname,response){
console.log("Routing request for"+pathname);
if(typeof handle[pathname] === 'function'){
handle[pathname](response);
}else{
console.log("No handle for" + pathname);
}
} module.exports.route=route;

这样就可以在handle中,用response对象,响应给页面内容了

var fs = require("fs");

function home(response){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/index.html","utf8").pipe(response);
} function review(response){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/review.html","utf8").pipe(response);
} function api_records(response){
response.writeHead(200,{"Content-Type":"application/json"});
var jsonObj={name:"lili",job:"coder",age:18};
response.end(JSON.stringify(jsonObj));
} module.exports={
home,
review,
api_records
}

此时,我们在localhost:3000  分别输入 /     /home    /review    /api_records    都会响应出不同的内容!!

下面处理一下,当没有对应路径的方法时,跳转到404页面:

在router.js中变动:

var fs = require("fs");

function route(handle,pathname,response){
console.log("Routing request for"+pathname);
if(typeof handle[pathname] === 'function'){
handle[pathname](response);
}else{
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/404.html","utf8").pipe(response);
}
} module.exports.route=route;

以上就是 重构路由代码的整个过程

成型路由代码

上线的重构过程有些乱,下面把整个路由重构后的代码帖出来:

api.js:

var server = require("./server");
var router = require("./router");
var handler = require("./handler"); var handle = {}; handle["/"]=handler.home;
handle["/home"]=handler.home;
handle["/review"]=handler.review;
handle["/api_records"]=handler.api_records; server.startServer(router.route,handle);

server.js:

var http = require("http");

var startServer = function(route,handle){
var onRequest = function(request,response){
console.log("request received"+request.url);
route(handle,request.url,response); } var server = http.createServer(onRequest);
//最后让服务器监听一个端口
server.listen(3000,"127.0.0.1");//还可以加第二个参数 127.0.0.1代表的是本地 console.log("server started on localhost port 3000");//加一个服务器启动起来的提示
} module.exports.startServer=startServer;

router.js:

var fs = require("fs");

function route(handle,pathname,response){
console.log("Routing request for"+pathname);
if(typeof handle[pathname] === 'function'){
handle[pathname](response);
}else{
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/404.html","utf8").pipe(response);
}
} module.exports.route=route;

handler.js:

var fs = require("fs");

function home(response){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/index.html","utf8").pipe(response);
} function review(response){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/review.html","utf8").pipe(response);
} function api_records(response){
response.writeHead(200,{"Content-Type":"application/json"});
var jsonObj={name:"lili",job:"coder",age:18};
response.end(JSON.stringify(jsonObj));
} module.exports={
home,
review,
api_records
}

上面就是成型的路由代码了,以后再添加新的路由,我们只需要该两处地方,1是,api中路径与handle方法的对应关系,2是,在handler.js中新增对应的方法!!!

比如说,我们加个text的路由,让它响应文本内容

api.js中:

var server = require("./server");
var router = require("./router");
var handler = require("./handler"); var handle = {}; handle["/"]=handler.home;
handle["/home"]=handler.home;
handle["/review"]=handler.review;
handle["/api_records"]=handler.api_records;
handle["/text"]=handler.text; server.startServer(router.route,handle);

handler.js中:

var fs = require("fs");

function home(response){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/index.html","utf8").pipe(response);
} function review(response){
response.writeHead(200,{"Content-Type":"text/html"});
fs.createReadStream(__dirname+"/review.html","utf8").pipe(response);
} function api_records(response){
response.writeHead(200,{"Content-Type":"application/json"});
var jsonObj={name:"lili",job:"coder",age:18};
response.end(JSON.stringify(jsonObj));
} function text(response){
response.writeHead(200,{"Content-Type":"text/plain;charset=UTF-8"});
response.end("文本内容");
} module.exports={
home,
review,
api_records,
text
}

ok!!!

上一篇:【转载】10 个实用技巧,让 Finder 带你飞


下一篇:nodejs+express创建一个简单的服务器