梳理框架流程

非原创

本文转自https://github.com/a415432669/-front_end_notebook/tree/master/Node/day6/%E6%96%87%E6%A1%A3

1浏览器发送请求

    1. 用户输入网址地址

http://127.0.0.1/

    2. 浏览器根据请求转变成HTTP的请求包

GET / HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

2服务器接受到请求

​    1. http模块里中实例化的server对象,server对象监听每一次浏览器发送过来的请求,每次的请求都会触发`request`事件
 

this.server.on('request',(req,res)=>{})

    2. 将HTTP的请求包转化成req的请求对象,并且传入到请求事件触发的函数中。
    3. 会创建生成1个res响应对象,这个对象可以帮助我们快速的实现HTTP的响应

3解析请求路径,调用不同的页面渲染函数

    1. 正则匹配方式进行对路径的匹配
     2. 以匹配的正则字符串作为KEY,找到需要调用执行的渲染函数

//循环匹配正则路径
for(let key in this.reqEvent){

    let regStr = key
    let reg = new RegExp(regStr,'igs');
    console.log(regStr,reg)
    if(reg.test(req.url)){
        this.reqEvent[key](req,res)
        resState = true
        break;
    }
}

3. 调用页面的执行函数

app.on('/movies/[01]',(req,res)=>{})//这里的箭头函数即为真正匹配到的页面时执行的函数

4. 调用模板的渲染函数

res.render(movies[index],'./template/index0.html')

5. 执行渲染函数

function render(options,path){
    fs.readFile(path,{encoding:"utf-8",flag:"r"},(err,data)=>{
        if(err){
            console.log(err)
        }else{
            //数组变量的替换
            data = replaceArr(data,options)
            //单个变量的替换
            data = replaceVar(data,options)
            //最终输出渲染出来的HTML
            this.end(data)
        }
    })
}

6. 数组变量的替换

function replaceArr(data,options){
    //匹配循环的变量,并且替换循环的内容
    let reg = /\{\%for \{(.*?)\} \%\}(.*?)\{\%endfor\%\}/igs
    while(result = reg.exec(data)){
        let strKey = result[1].trim();//提取变量时,去掉左右两边的空格
        //通过KEY值获取数组内容
        let strValueArr = options[strKey]
        let listStr = ""
        strValueArr.forEach((item,i)=>{
            //替换每一项内容里的变量
            listStr = listStr + replaceVar(result[2],{"item":item})
        })
        data = data.replace(result[0],listStr)
    }
    return data;
}

7. 单个变量的替换

function replaceVar(data,options){
    let reg = /\{\{(.*?)\}\}/igs
    let result;
    console.log(options)
    while(result = reg.exec(data)){
        //去除2边的空白
        let strKey = result[1].trim()
        
        console.log(strKey)// item,item.abc
        let strValue = eval('options.'+strKey);//执行字符串作为JS表达式,并将计算出来的结果返回
        data = data.replace(result[0],strValue)
    }
    return data
}

4如果是请求静态文件,那么就按照静态文件的形式输出

1. 首先判断是否响应过,如果没有响应过,可以判断是否为静态文件,如果是静态文件就正常的输出
2. 否则,就输出404

if(!resState){
    if(pathObj.dir==this.staticDir){
        res.setHeader("content-type",this.getContentType(pathObj.ext))
        let rs = fs.createReadStream('./static/'+pathObj.base)
        rs.pipe(res)
    }else{
        res.setHeader("content-type","text/html;charset=utf-8")
        res.end("<h1>404!页面找不到</h1>")
    }
}

5.RES响应对象 将res设置的内容最终转化成http的响应包

HTTP/1.1 200 OK
content-type: text/html;charset=utf-8
Date: Sat, 30 Nov 2019 07:01:36 GMT
Connection: keep-alive
Content-Length: 46
<h1>这是首页</h1><img src='./abc/cxk.jpg'>

6浏览器解析响应包,并将html渲染在页面上

猜你喜欢

转载自blog.csdn.net/small_rain_/article/details/112488710
今日推荐