美文网首页
框架流程

框架流程

作者: 十八句 | 来源:发表于2020-07-23 21:08 被阅读0次

    一、浏览器发送请求

    1、用户输入网址
    http://127.0.0.1/
    
    2、浏览器根据请求转变HTTP的请求包
    GET / HTTP/1.1
    Host: 127.0.0.1
    Connection: keep-alive
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Sec-Fetch-Site: none
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    

    二、服务器接收到请求

    1、http模块里实例化的server对象,server对象监听每一次浏览器发送过来的请求,每次的请求都会触发request事件
    this.server.on("request",(req,res)=>{})
    
    2、将HTTP的请求包转换成req的请求对象,并且传入到请求事件触发的函数中。
    3、会创建生成一个res响应对象,这个对象可以帮助我们快速的实现HTTP的响应。

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

    1、正则匹配方式进行对路径的匹配。
    2、以匹配的正则字符串作为KEY,找到需要调用执行的渲染函数
    //循环匹配正则路径
    for(let key in this.reqEvent){
        let regStr = key
        let reg = new RegExp(regStr,'igs');
        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/index1.html')
    
    5、执行渲染函数
    function render(options,path) {
        fs.readFile(path,{encoding:"utf-8",flag:"r"},(err,data)=>{
            if(err){
                console.log(err)
            }else{
                try{
                    data = replaceArr(data,options)
                    data = replaceVar(data,options)
                }catch(error){
                    console.log(error)
                }
                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;
        while (result = reg.exec(data)){
            //去除两边的空白
            let strKey = result[1].trim();
            //options.item
            let strValue = eval('options.'+strKey);//执行字符串作为JS表达式,并将计算出来的结果返回
            data = data.replace(result[0],strValue)
        }
        return data
    }
    

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

    1、首先判断是否响应过,如果没有响应过,可以判断是否为静态文件,如果是静态文件就正常的输出
    2、否则就输出404
    if(!resState){
        try{
            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>")
            }
        }catch(error){
            console.log(error)
        }
    }
    

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

    HTTP/1.1 200 OK
    content-type: text/html;charset=utf-8
    Date: Thu, 23 Jul 2020 12:17:19 GMT
    Connection: keep-alive
    Content-Length: 53
    
    正文内容
    

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

    相关文章

      网友评论

          本文标题:框架流程

          本文链接:https://www.haomeiwen.com/subject/clkklktx.html