我们打开浏览器浏览网页时,点击上面不同的模块,地址栏中的路由会发生相应的变化,从而,浏览器向服务器发起请求的内容也会发生改变,那么服务端,是如何来做的呢?
服务端也是,通过路由来做出不同的响应的,我们已经知道,服务器对象的参数有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!!!