请求管线、中间件

管线、中间件、路由图解:


 

1. 请求管线

(1)request-line  1

express:服务器集成,在收到请求之后放入到请求管线中,从管线口开始逐个寻找能够匹配上url路径和请求处理的函数,找到这个能匹配的处理函数之后就用这个处理函数来解决本次请求,找不到继续...

var express = require("express");
var app = express();

app.use 方法,在请求管线中添加一个匹配条件的请求.get .post能够在请求管线中添加一个请求处理函数,这些添加的处理函数,必须要请求方式和url路径都能匹配上才能处理该请求;

 next表示找不到是否要继续

app.use(function (req, res, next) {
    console.log(1);
    next(); //>>>login
    console.log(2);
});

function isLogin(req, res, next) {
    var str = "已经登录";
    if (str) {
        console.log("已经登录");
        next(); //....
    } else {
        console.log("请先登录");
        res.send("请先登录");
    }
}
app.get("/api/login", isLogin);
// get post请求 第一个参数是接口地址,从第二个参数开始写这个接口
// 匹配的请求处理函数,可以一次性添加多个
app.get("/api/login2", isLogin, function (req, res) {
    res.send("api2");
});

// 管线里面的任意一个函数,请求都要经过
app.use(function (req, res) {
    res.send(404, "<h1>您访问的页面不存在</h1>");
})

app.listen(3000, function () {
    console.log("Server-Running...");
});

(2)request-line  2

var express = require("express");
var app = express();

function utf8(req, res, next) {
   // 设置响应头 res.set({})批量设置响应头
   // Content-Type 响应头中设置编码可以解决乱码问题
   res.set("Content-Type", "text/html;charset=utf-8");
   console.log("设置字符编码");
   next();
}

function first(req, res, next) {
   console.log(" 这是第一个请求处理函数");
   next();
}

function first(req, res, next) {
   console.log(" 这是第一个请求处理函数");
   next();
}

function second(req, res, next) {
   console.log(" 这是第二个请求处理函数");
   next();
}

function third(req, res, next) {
   console.log(" 这是第三个请求处理函数");
   next();
}

app.get("/", third, first, second, function (req, res) {
   res.send("这是最后一个请求处理的函数");
});

// 中间部分可以写成一个数组
app.get("/", [utf8, first, second, third], function (req, res) {
   res.send("这是最后一个请求处理的函数");
});
app.get("/hi/:age", utf8, first, second, third, function (req, res) {
   var name = req.query.name;
   // params 参数集合
   var age = req.params.age;
   console.log(req.params);
   res.send(`你好${name},${age},很高兴认识你`);
   /*
   获取客户端数据:
   1.获取url中的querystring(?后面的name=value,通过GET方式发送) req.query.name;
   2.获取请求体中的数据(通过post请求发送,有多种编码方式)req.body.name
   如果是urlencoded编码 需要通过body-parser模块设置
   如果是multipart/form-data需要用multer模块(图像上传会讲到)
   3.获取cookie中的数据 req.cookie.name
   4.获取请求头中的数据
   req.get('name');
   5.获取url路径path中的数据
   req.params.age
   需要设置请求地址木事/hi/:age:目的是为了将参数放到path中
   相当于将参数放到了QueryString中更容易被人和搜索引擎识别
   "/hi/:age"这种url叫做友好url ,url friendly url
   */
});
app.listen(3000, function () {
   console.log("Server-Running...");
});

 

2. 中间件

在express服务中,经常会用到一些针对于全部请求的处理函数,例如body-parser,static,session...这些都是请求处理函数都要用到的功能,(请求进行初步处理,并且进行加工,然后在传递给真正的业务逻辑接口函数),凡是满足这种定义的请求处理函数都叫做中间件;

(1)导入模块

var express = require("express");
var app = express();
var path = require("path");
var fs = require("fs");
var url = require("url");

(2)仿制express中静态文件夹的功能     1.用户只需要输入接口,不需要输入文件的绝对路径,可以读出来默认启动页的内容

function static(staticPath) {
    function f(req, res, next) {
        // url转成url对象
        var urlObj = url.parse(req.url);
        // 把url中路径和静态文件夹进行拼接>>>完整的url
        var filePath = path.join(staticPath, urlObj.pathname);
        // 读取文件 根据路径读取文件,带一个读取的回调
        fs.lstat(filePath, function (err, s) {
            if (!s) {
                // 文件不存在,继续寻找请求处理管线中的其他请求处理函数
                next();
            } else {
                // 检测当前路径读取的内容是不是文件夹目录内容
                // isDirectory()检测是否为文件夹  返回布尔值
                if (s.isDirectory()) {
                    filePath = path.join(filePath, "index.html");
                }
                fs.readFile(filePath, function (err, data) {
                    res.end(data.toString());
                });
            }
        });
    }
    return f;
}
app.use(static("www"));

(3)手写body-parser

function bodyParser(req, res, next) {
    // 判断是不是post请求
    if (req.method == "POST") {
        // 前端表单的提交  p1.name 该请求是前端的表单提交
        if (req.headers["content-type"] == "application/x-www-form-urlencoded") {
            // 处理数据 初始化一个buffer  0代表清空内存
            var data = Buffer.alloc(0);
            // on这个方法是持续性读取数据
            // 回调表示此次读出来的data
            req.on("data", function (d) {
                // 迅雷下载
                data += d;
            });
            // 读取完毕
            req.on("end", function () {
                //  转化成可以用的数据 :把接收到的请求体字符串转成对象
                var obj = {};
                var params = data.split("&");
                params.forEach(function (el) {
                    var vn = el.split("=")[0]; //键
                    var vv = el.split("=")[1]; //值
                    obj[vn] = vv; //为对象附上属性和值obj
                });
                // 把当前贮备好的请求体对象放入到req.body里
                req.body = obj;
                next();
            });
        } else {
            next();
        }
    } else {
        next();
    }
}
app.use(bodyParser);

(4) test

app.post("/api/post", function (req, res) {
    res.send("这是/api/post的post接口");
    console.log(req.body.username);
});
app.listen(3000, function () {
    console.log("Server-Running...");
});

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值