express 프레임 워 크 의 일치 경로 체 제 를 깊이 이해 하 다.

6127 단어 node.jsexpress
현재 node 의 웹 프레임 워 크 는 매우 많 습 니 다.express 외 에 도 koa egg 등 이 있 습 니 다.그러나 이들 은 본질 적 으로 원생 node 프레임 워 크 를 기반 으로 한 http 입 니 다.사실 틀 은 모두 크게 다 르 지 않 고 주로 참관 과 학습 이다.이 글 은 node 에서 구덩이 에 오 르 는 자신의 경험 과 수확 을 기록 하고 있 습 니 다~
본 고 는 주로 express 의 기능 중 하 나 를 실현 하고 경로 와 일치 합 니 다.
간단 한 정적 경로 와 일치 합 니 다일치 하 는 동적 경로우선 express 를 살 펴 보 겠 습 니 다.
const express = require('express');

let app = new express();

app.get('/',(req,res)=>{
    res.end('home Page.');
});

app.get('/center',(req,res)=>{
    res.end('center Page.');
});

/**                   */
 app.get('/product/:id/:name',(req,res)=>{
     res.end(JSON.stringify(req.params));
 });

/**                 404 */
app.all('*',(req,res)=>{
    res.end('404');
});

let port = 3000;

app.listen(port,()=>{
    console.log(`Server is start on port ${port}`);
});

ok.코드 는 간단 합 니 다.express 를 도입 하여 new 는 express 인 스 턴 스 를 사용 하여 몇 가지 경 로 를 썼 고 마지막 으로 로 컬 서 비 스 를 시작 했다.
코드 두 번 째 줄 에서 우 리 는 도 입 된 express 를 new 에 게 보 내 서 express 내부 에서 하나의 function 으로 되 돌아 간 다 는 것 을 설명 합 니 다.
좋 습 니 다.참 새 는 작 지만 오장 이 모두 갖 추어 져 있 습 니 다.우 리 는 오늘 express 의 이러한 기능 을 실현 하 겠 습 니 다.
let http = require('http'); /** express  http */
let url = require('url'); /**           */
/** express   methods                */
let methods = require('methods');

function application(){
    /** 1 express        
     *       http.createServer     
    */
    let app = (req,res) => {
        /** 1.1 url               /user */
        let { pathname } = url.parse(req.url);
        /** 1.2                      */
        let requestMethod = req.method.toLowerCase();
        /** 1.3                       routes        */
        for(let i = 0; i < app.routes.length; i++){
            /** 1.4                      */
            let { path, method, cb } = app.routes[i];
            if((pathname===path||path==='*') && (requestMethod===method)||method==='all'){
                /** 1.5               */
                return cb(req,res);
            }
        }
        /** 1.6           */
        res.end(`Cannot found ${pathname}/${requestMethod}`);
    }

    /** 2               */
    app.routes = [];
    /** 2.1  methods          all        */
    [...methods,'all'].forEach((method)=>{
        app[method] = function(path,cb){
            /** 2.2                       
             * path:    method:     cb:  
            */
            let layer = { path, method, cb };
            app.routes.push(layer);
        }
    });

    /** 3      */
    app.listen = function(...arguments){
        /** 3.1   http createServer    app    */
        let server = http.createServer(app);
        server.listen(...arguments);
    }
    return app;
}

/** 4         */
module.exports = application;


코드 위 에 관람 번호 가 자세히 표시 되 어 있 습 니 다.1,2,3.순서대로 보면 됩 니 다.
우리 가 손 으로 쓴 전체 express 는 하나의 함수 함수 안에 하나의 함 수 를 return 했다.node 네 이 티 브 프레임 http 방법 으로 이 함 수 를 포장 하고 마지막 으로 전체 함수 module.exports 를 내 보 냅 니 다.마지막 으로 프로젝트 를 시작 합 니 다.브 라 우 저 나 postman 호출 인 터 페 이 스 를 통 해 일부 express 기능 을 실현 할 수 있 음 을 발 견 했 습 니 다.그러나 한 가 지 는 이때 우리 가 실현 할 수 있 는 것 은 정적 인 경로 일 뿐 입 니 다.만약 에 경로 파라미터 가 있 으 면 예 를 들 어/produt/:id/:name 입 니 다.결 과 는 기대 에 부합 되 지 않 는 다.개조:
코드 위 에 관람 번호 가 자세히 표시 되 어 있 습 니 다.1,2,3.순서대로 보면 됩 니 다.
let http = require('http');
let url = require('url');
let methods = require('methods');

function application(){
    let app = (req,res) => {
        let { pathname } = url.parse(req.url);
        let requestMethod = req.method.toLowerCase();
        for(let i = 0; i < app.routes.length; i++){
            let { path, method, cb } = app.routes[i];
            /** 7       path             */
            if(path.params){
                /** 8                      true */
                if(path.test(pathname)){
                    /** 9                */
                    let [, ...otherParams] = pathname.match(path);
                    /** 10   reduce()               
                     *    req.params 
                     */
                    req.params = path.params.reduce(
                        (memo,key,index)=>(
                            memo[key]=otherParams[index],memo
                        ),{}
                    );
                    /** 11            */
                    return cb(req,res);
                }
            }

            if((pathname===path||path==='*') && (requestMethod===method)||method==='all'){
                return cb(req,res);
            }
        }
        res.end(`Cannot found ${pathname}/${requestMethod}`);
    }

    app.routes = [];
    [...methods,'all'].forEach((method)=>{
        app[method] = function(path,cb){
            let layer = { path, method, cb };

            /** 1                    */
            let params = [];
            /** 2        :            */
            if(path.includes(':')){
                /** 3           path        
                 *                               
                 */
                layer.path = new RegExp(path.replace(/:([^\/]*)/g,function(){
                    /** 4         key   params    */
                    params.push(arguments[1]);
                    /** 5                           : */
                    return '([^\/]*)';
                }));
                /** 6                 path params  */
                layer.path.params = params;
            }

            app.routes.push(layer);
        }
    });

    app.listen = function(...arguments){
        let server = http.createServer(app);
        server.listen(...arguments);
    }

    return app;
}

module.exports = application;



먼저 이 동적 경로 에 정규 로 일치 하고 이 동적 경로 의 path 를 정규 로 바 꾸 어 배열 에 넣 고 진정한 동적 경로 가 오 기 를 기다 릴 때 경로 배열 에서 이 동적 경로 의 경 로 를 가 져 옵 니 다.즉,방금 교 체 된 정규 로 이 동적 경로 뒤의 매개 변 수 를 일치 시 키 면 됩 니 다.
이상 을 통 해 동적 경로 의 매개 변 수 를 얻 을 수 있 습 니 다.위의 그림:
코드 는 git mock-express 에 있 습 니 다.

좋은 웹페이지 즐겨찾기