Node中间件和路由器

中间件(需要使用express)

本质上是一个函数,包含三个参数

requestresponsenext

作用

  • 执行任何代码
  • 修改请求和响应对象
  • 终结请求-响应循环(让一次请求得到响应)
  • 调用堆栈中的下一个中间件或者路由

分类

  • 应用级中间件(全局)(过滤非法的请求,例如防盗链)

  • 第三方中间件(通过npm下载的中间件)

  • 内置中间件(框架内部内置的中间件)

  • 路由中间件(Router)

应用中间件

第一种使用全局中间件

所有的请求都会进入该中间件

const express = require('express');

const app = express();

// 应用级中间件
app.use((req, res, next) => {
    res.send('这是中间件的响应');
});

// 根路由
app.get('/', (req, res) => {
    res.send('这是根路由响应');
});

app.get('/1', (req, res) => {
    res.send('这是一级路由');
});

app.get('/1/2', (req, res) => {
    res.send('这是二级路由');
});

app.listen(8080, (err) => {
    if (!err) {
        console.log('ok');
    } else {
        console.log(err);
    }
});
  • 访问根路由

在这里插入图片描述

  • 访问一级路由

在这里插入图片描述

  • 访问二级路由

在这里插入图片描述

访问的时候我们发现,无论是请求的哪个路由,都是返回应用级中间件的响应,且后序路由不在执行,当我们调用next后,便可以访问到目标路由。

将应用级中间件写在请求的任意位置,请求会依照代码顺序执行,若是执行到该中间件,那么它科能会影响到下一级中间件(若在一级与二级路由之间设置一个应用级中间件且无next,那么智能响应一级路由之前的路由,二级路由是无法访问到的)

在express中,定义路由和中间件的时候,根据定义顺序,将每一个中间件或者路由放在一个类似于数组的容器中,当请求过来的时候,依次从容器中取出中间件和路由进行匹配,如果匹配你成功,则交由该中间件或者路由处理,如果如果全局中间件定义在最开始的位置,那么所有的请求都会进入该中间件。

对于浏览器来说,每一次请求只会有一个请求对象,和一个响应对象,后续路由使用的req和res都是同一个req,res对象

注意: 在中间件中无法在next调用之前使用返回响应

函数式中间件的定义方式

const express = require('express');

const app = express();

// 函数式应用级中间件
function middleware(request, response, next){
    // 应用级中间件
	app.use((req, res, next) => {
  	  res.send('这是中间件的响应');
	});
}

// 根路由
app.get('/', (req, res) => {
    res.send('这是根路由响应');
});

// 使用应用中间件
app.get('/1', middleware, (req, res) => {
    res.send('这是一级路由');
});

app.get('/1/2', (req, res) => {
    res.send('这是二级路由');
});

app.listen(8080, (err) => {
    if (!err) {
        console.log('ok');
    } else {
        console.log(err);
    }
});

区别:更加灵活,可以在需要的地方使用(依据请求的路径选择使用中间件),第一种方式更适合所有请求需要做某种操作时使用。

使用方式:传入到路由的第二个参数的位置。


第三方中间件

通过npm和yarn下载的中间件

内置中间件

express内置有一些中间件

静态文件

可以通过express.staict设置静态文件

app.use(express.staict(__dirname + '/public'));
//  将当前文件夹下的public文件夹设置为静态访问

注意:访问静态文件夹内的文件需要添加上后缀

路由器

express框架中引入了路由器的概念,使用了路由器可以使代码结构功能更加清晰,便于维护

在这里插入图片描述

server文件

/*
* 基础页面
* */

const express = require('express');

const app = express();

// 解析post传递的参数
app.use(express.urlencoded({extended: false}));
// 解析json
app.use(express.json());

// 加载路由器
const {router} = require('./Router/router');

// 使用路由器中间件
app.use(router());

app.listen(3300, (err) => {
    if (err) {
        console.log(err);
    } else {
        console.log('ok');
    }
});

router

/*
* 路由器模块
* */

// 加载路由方法
const {Router} = require('express');

// 创建路由器实例
const router = Router();

// 加载 fs文件模块 解析绝对路径方法
const {moudule:{fs, resolve}} = require('../module/module');

router.get('/', (req, res) => {

    let path = resolve(__dirname, '../public/index.html');

    let html = '';

    let rs = fs.createReadStream(path, {
        highWaterMark: 10 * 1024 * 1024
    });

    rs.on('open', () => {
        console.log('可读开启');
    });

    rs.on('close', () => {
        console.log('可读关闭');
        res.send(html);
    });

    rs.on('data', (data) => {
        html += data;
    });


});

router.post('/login', (req, res) => {

    let {body: {uname, pwd}} = req;

    if (pwd === '0059') {
        res.send('你好' + uname);

        // res.redirect(302, '/');
    } else {
        res.send('password is error');
    }

});

// 暴露路由器对象
module.exports.router = function () {
    return router;
}

module

/*
* module 核心模块
* */
 // 文件系统
const fs = require('fs');

// path模块
const {resolve} = require('path');

// 暴露
module.exports.moudule = {
    fs,
    resolve
};

public

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        input {
            width: 200px;
            height: 30px;
            outline: 0;
            font-size: 18px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        input:hover {
            box-shadow: 0 0 1px 1px aqua;
        }

        button {
            padding: 10px 20px;
            outline: 0;
            color: #666;
            font-weight: 700;
            font-size: 18px;
            cursor: pointer;
            border-radius: 10px;
        }

        div {
            margin-top: 30px;
        }
    </style>
</head>
<body>
<h1>服务器接收Get和post请求测试</h1>

<!--提交信息-->
<input type="text" name="uname" placeholder="请输入姓名"><br><br>
<input type="password" name="pwd" id="" placeholder="请输入密码"><br><br>
<button>提交</button>
<div></div>
<script>
    // 获取元素
    let btn = document.querySelector('button'),
        input = document.querySelectorAll('input'),
        div = document.querySelector('div'),
        bool = true;


    btn.addEventListener('click', () => {
        if (bool) {
            bool = false;

            let obj = {uname: input[0].value, pwd: input[1].value};

            let xml = new XMLHttpRequest();

            xml.timeout = 1200;

            xml.open('POST', 'http://localHost:3300/login', true);
            
            // 设置解析json格式的请求头
            xml.setRequestHeader("Content-type", "application/json; charset=utf-8");

            xml.addEventListener('readystatechange', () => {

                // 4 表示接收到全部响应数据
                // 3 表示接收到部分响应数据(响应中)
                // 2 表示已初始化(open调用)但是没有发送请求
                // 1 表示已初始化(open调用)但是没有调用send()
                // 0 表示未初始化(open未调用)
                try {
                    if (xml.readyState === 4) {
                        // 表示接收到全部响应数据了
                        if (xml.status >= 200 && xml.status < 300) {

                            div.innerHTML = xml.responseText;

                            bool = true;
                        }
                    }
                } catch (error) {
                    alert('出现未知错误!' + error);
                }
            });

            xml.send(JSON.stringify(obj));
        }
    });
</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值