详解express搭建http服务,通过路由和中间件获取静态文件和动态数据的实现原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解express搭建http服务,通过路由和中间件获取静态文件和动态数据的实现原理相关的知识,希望对你有一定的参考价值。

express方法

Express是一个简洁、灵活的node.js Web应用开发框架,是目前最流行的基于Node.js的Web开发框架. 它提供一系列强大的功能,比如:

模板解析
静态文件服务
中间件
路由控制

在node中使用express创建一个http请求,具体步骤如下:
1,引入express模块
2,执行express方法
3,express方法执行后返回一个http的监听函数,可以用返回的函数监听端口

通过使用中间件请求静态资源

express搭建服务

let express=require("express");
let app=express();
app.listen(8080);

express函数执行后,返回的是一个http的监听函数,就是http.createServer中的函数
在此函数上扩展了一个listen可以监听端口,app.listen就是基于以前封装的

app.listen=function (...arg) {
    require("http").createServer(app).listen(...arg)
}
app.listen(8080,()=>{
    "8080端口已开启"
})

基于express的监听函数app上扩展了很多的方法

express路由

必须method和path全都匹配上执行对应的callback
1.在处理请求路径和方式上,指明了请求的方式,包括get post delete put,RESTful风格中的动词,与之前相比不需在进行判断了

app.get("/sigin",function (req,res) {
    res.setHeader("content-type","text/plain;charset=utf-8");
    res.end("登录");
});
app.post("/sigin",function (req,res) {
    res.setHeader("content-type","text/plain;charset=utf-8");
    res.end("post登录");
});
//all表示所有的方法,*表示所有的路径,一般放到最后
app.all("*",function (req,res) {
    res.end("404")
})

若请求localhost:8080/sigin,则返回登录

参数路由:

在路径中针对同一路径,我们可以通过路由参数,区分查一个或者多个内容,所有的路由参数都放到req.params对象中,

app.get("/user",function (req,res) {
    res.end("select all")
});
app.get("/user/:id/:name",function (req,res) {
    res.end("select one"+req.params.id+req.params.name);
});

2.如果想拿到请求的路径参数可以使用app.params()方法拿到,此方法具有拦截功能,只有调用了next()方法后才继续往下走

app.param("id",function (req,res,next) {
    req.params.id=`你的学号是${req.params.id}`;
    //res.end("123")
     next();//调用了next就可以向下匹配,如果在这里结束了请求那就不走了

});
app.param("name",function (req,res,next) {
    req.params.name=`你的名字是${req.params.name}`;
    next();

})
app.get("/user/:id/:name",function (req,res) {
    res.header("content-type","text/plain;charset=utf-8");
    res.end("select one"+req.params.id+req.params.name);
});

响应成功返回内容:select one你的学号是1你的名字是md

中间键

访问到最终目标之前做一些事情,那么app.use()方法就可以
app.use()
1)功能

1.可以进行权限判断
2.可以对res和req的属性进行扩充
3中间键放在要执行的路径上面
4中间键默认情况下都匹配,可以指定匹配什么开头

2) 使用
在匹配路由,返回数据之前,如果我们想做一些事情,也可以使用中间件

 app.use(function (req,res,next) {//不调用next就不继续往下走
    console.log("过滤石头");
    req.stone="too big";
    res.end("hello");
    next();
    // next("错误");
});
app.use(function (req,res,next) {//不调用next就不继续往下走
    console.log("过滤沙子");
    req.sand="too small";
 next();
});
app.get("/foot",function (req,res) {
    console.log(req.stone,req.sand);
    res.end("foot");

})
app.get("/water",function (req,res) {
    console.log(req.stone,req.sand);
    res.end("water");

});
app.use(function (err,req,res,next) {
    console.log(err);
    next();
})

如果next()里面传了参数,中间键走拥有四个参数的方法,即最后的方法
3)方法封装原理

function app() {
    //每次调用use方法都会将方法存到数组中,默认调用数组的第一项,将next方法传递给数组中的函数,如果调用次函数  会继续执行数组中的下一项
    app.middlereware=[];

}
app.use=function (cb) {
    this.middlereware.push(cb);
};
app.use(function (res,req,next) {
    console.log(1);
    next();
});
app.use(function (res,req,next) {
    console.log(2);
    next();
});
app.use(function (res,req,next) {
    console.log(3);
});
let index=0;
function next() {
    app.middlereware[index++](null,null,next);
};
next();

扩展了res,req里的一些属性和方法

1)req上扩展的属性和方法
req.query.id 获取路由参数
req.path 获取路径

let express=require("express");
let app=express();
app.listen(8081);
app.get("/user",function (req,res) {
    console.log(req.query.id);//express扩展的属性
    console.log(req.url);//获取整个路径包括问号
    console.log(req.path);//express扩展的属性
    console.log(req.headers);//所有的都是小写
    console.log(req.method);//所有的方法都是大写
})

2)res上扩展的属性和方法
1,res,json(),直接返回json格式的字符串返回
以前响应返回的数据需要通过JSON.stringFly()转化之后才能返回

app.get("/json",function (req,res) {
    res.json({name:"你好",age:8});//响应json
});

2,以前返回一个页面文件需要通过fs读取,现在可以通过res.sendFile()方法拿到,路径必须是绝对路径

app.get("/",function (req,res) {
    // res.sendFile("./index.html",{root:__dirname});不能通过../查找(root是不支持的)想读取到确切的文件 用path模块进行拼接即可
    res.sendFile(require("path").join(__dirname,"..","index.html"))
});

3.返回状态码无需通过res.setStateCode(),可以使用res.send(),也可以返回中文,无需设置响应头的类型,可以根据返回的数据类型,自动设置返回的响应头类型

app.get("/send",function (req,res) {
    // res.send("中文")
    res.send(200)
});

send()方法的封装

app.use(function (req,res,next) {
    res.mySend = function (data) {
        if(typeof data === ‘object‘){
            res.setHeader(‘Content-Type‘,‘application/json;charset=utf8‘);
            return res.end(JSON.stringify(data));
        }
        if(typeof data === ‘string‘){
            res.setHeader(‘Content-Type‘,‘text/plain;charset=utf8‘);
            return res.end(data);
        }
        if(typeof data === ‘number‘){
            res.statusCode = data;
            res.end(require(‘_http_server‘).STATUS_CODES[data]);
        }
    };
    next();
});
app.get(‘/send‘,function (req,res) {
    res.mySend(500);
}

路由拆分(设置二级路由)获取动态数据

可以通过express上可以通过express.Router()和中间件设置子级路由把所有的子路由都放在一个routes文件夹下,该文件夹下可以放置多个相同的模块,每个模块中都需要引入express模块,设置子路由的路径和相应的方法,并将该模块导出moudle.export={},然后在主模块中引用routes文件夹子模块,通过require,然后通过中间件use()方法,匹配二级路由

let express = require(‘express‘);
let app = express();
let router = express.Router();
router.get(‘/login‘,fn)
app.use(‘/user‘,router);

bodyParser

app.use(bodyParser.json()); // 解析json application/json
app.use(bodyParser.urlencoded({extented:true})); // 解析表单 application/x-www-form-urlencoded
  • ejs用法

    <!--引入模板-->
    <%include header.html%>
    <!--取值-->
    <h1><%=username%></h1>
    <p><%=password%></p>
    <!--js语句-->
    <%arr.forEach(item=>{%>
    <li><%=item%></li>
    <%})%>
    <!--转译-->
    <%-html%>

    ejs模板渲染的文件默认是带有ejs后缀的文件,并且是放在当前目录下的view文件夹,并且在拿到数据后想要通过render函数渲染数据的话,渲染的模板文件是带有ejs后缀的,可以通过中间件把模板文件的后缀更改成html,view文件夹的名字更改为static文件

//更改默认模板的后缀
app.engine(‘html‘,require(‘ejs‘).__express);
// 更改模板路径,默认叫views
app.set(‘views‘,‘static‘);
// 配置默认模板后缀名字
app.set(‘view engine‘,‘html‘);

静态服务中间件

通过express.static()请求文件文件

app.use(express.static(‘文件夹‘))

重定向

res.redirect(‘路径‘);

由此我们就可以基于express方法搭建一个http,服务,通过express.Router(),搭建子级路由,获取和响应数据,通过express.static()方法可以请求静态资源,通过app.use()中间,对请求的路由,数据,响应的数据进行再处理,从而提高了整个hhtp请求的可控性




















以上是关于详解express搭建http服务,通过路由和中间件获取静态文件和动态数据的实现原理的主要内容,如果未能解决你的问题,请参考以下文章

Express4.x之中间件与路由详解及源码分析

express框架

Node.js Express 框架

Node.js Express 框架

Node.js Express 框架

Node.js:Express 框架