zoukankan      html  css  js  c++  java
  • 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!!!

  • 相关阅读:
    计算机编程的24条法则
    爱的十个秘密10.热情的力量
    爱的十个秘密9.承诺的力量
    CPU信息的获得(转自大富翁)
    从编程员的角度理解 NTFS 2000:流和硬链接
    爱的十个秘密8.沟通的力量
    Delphi面向对象编程的20条规则(转自太平洋电脑网)
    程序读取计算机设备管理器中各设备的状态(启用/禁用)?(转自大富翁)
    关于NTFS文件系统中的数据流问题
    Windows新版算号器技术原理
  • 原文地址:https://www.cnblogs.com/fqh123/p/11257078.html
Copyright © 2011-2022 走看看