1. 全局中间件
const express = require("express");
const { allRouter } = require("./router");
const fs = require("fs");
// 1. 创建一个服务器
const server = express();
/**
* 后续新增功能: 将每一次请求, 记录到 隔壁的 index.txt 文件
*
* 因为每一次请求进入到对应的 静态资源 或者 接口处理后, 就不会再触发后续的代码了
*
* 所以当前的全局中间件, 必须书写在 1.1 和 1.2 之前
*
*
* 每一个自定义的中间件, 进入后请求到此暂时中断, 需要我们指定是否继续向下运行
* 如果需要向下运行, 那么需要借助当前函数的第三个形参, 这个形参是一个函数, 当你调用之后, 就会向下运行到下一个环节 注意 第三个形参 在中间介代码末尾运行
*/
1. 全局中间件
server.use((req, res, next) => {
fs.appendFile(
"./index.txt", // req.url 浏览器中发起请求的地址 ,有html,js等
`时间: ${new Date()} ---> 请求地址: ${req.url} \n`,
() => next()
);
});
// 1.1 引入静态资源
server.use("/static", express.static("./client"));
// 1.2 配置接口处理
server.use("/api", allRouter);
// 2. 给服务器添加一个端口号
server.listen(8080, () => console.log("服务器启动成功"));
/**
* 中间件的分类
*
* 1. 全局中间件
* 服务器.use(参数1, 参数2)
* 参数1: 是表示以什么路径开头
* 参数2: 如果路径的开头符合 参数1 的要求, 那么执行参数2 的代码
*
* 参数1 可以不传递
*
* 2. 路由中间件
* 路由表.use(参数1, 参数2)
* 参数1: 是表示以什么路径开头
* 参数2: 如果路径的开头符合 参数1 的要求, 那么执行参数2 的代码
*
* 参数1 可以不传递
*
* 3. 请求中间件
* 在 请求的处理函数前, 在书写一个 函数
*
*
* 4. 全局错误处理中间件
*/
路由中间件
// 内部存储购物车相关的路由分表
const express = require("express");
const { cartList, cartAddItem, cartDelItem } = require("../controller/cart");
// 1. 创建一张路由分表
const cartRouter = express.Router();
// 1.1 因为当前的 购物车接口全都需要登陆过才能使用, 所以我们将 token 的校验, 添加到 路由中间件中
cartRouter.use((req, res, next) => {
//req.headers 就是请求头
if (req.headers.authorization === "10086") {
/**
* 当前 分支能够执行, 说明按照我们目前的约定 token 一定没有问题
* 那么我们就不再做其他的处理, 让请求继续向下运行即可
*/
next()
} else if (req.headers.authorization === "10010") {
res.send({
code: 0,
msg: "token 过期, 请重新登陆获取最新的 token",
});
} else if (req.headers.authorization === undefined) {
res.send({
code: 0,
msg: "您没有传递 token, 请正确传递 token",
});
} else {
res.send({
code: 0,
msg: "token 不正确",
});
}
});
// 2. 向路由分表上添加一些接口
cartRouter.get("/list", cartList);
cartRouter.get("/addItem", cartAddItem);
cartRouter.get("/delItem", cartDelItem);
// 3. 导出当前路由分表, 给路由总表使用
exports.cartRouter = cartRouter;
请求中间介
const express = require("express");
const { cartList, cartAddItem, cartDelItem } = require("../controller/cart");
// 创建一个 路由分表表
const Router = express.Router();
// 路由中间件
Router.use((req, res, next) => {
if (req.headers.authorization === "10086") {
next();
} else if (req.headers.authorization === "10010") {
res.send({
code: 0,
msg: "token 过期",
});
} else if (req.headers.authorization === undefined) {
res.send({
code: 0,
msg: "您没有传递 token",
});
} else {
res.send({
code: 0,
msg: "token 不正确",
});
}
});
// 向路由分表上添加一些接口 请求中间介
Router.get(
"/list",
(req, res, next) => {
/**
* 1. 判断用户有没有传递 用户ID, 并且去数据库查询有没有对应的ID
*
* 在 express 框架中, 一个接口的请求报文中的参数, 会被 express 解析到 req.query 中
*
* 但是注意, 只有 get 请求会被解析, post 请求 不会被解析, post 需要我们像以前写原生服务器一样, 自己解析
*/
// console.log(req.query);
if (req.query.userid === undefined) {
return res.send({
code: 0,
msg: "参数不够",
});
}
next();
},
cartList
);
Router.get(
"/addItem",
(req, res, next) => {
// 1. 判断用户有没有传递 用户ID 和 商品ID
const { userid, goodsid } = req.query;
if (!userid || !goodsid) {
return res.send({
code: 0,
msg: "参数不够",
});
}
next();
},
cartAddItem
);
Router.get(
"/delItem",
(req, res, next) => {
// 1. 判断用户有没有传递 用户ID 和 商品ID
const { userid, goodsid } = req.query;
if (!userid || !goodsid) {
return res.send({
code: 0,
msg: "参数不够",
});
}
next();
},
cartDelItem
);
exports.cartRouter = Router;
全局错误处理中间件
const express = require("express");
const { allRouter } = require("./router");
const fs = require("fs");
// 创建服务器
const server = express();
// 全局中间件
server.use((req, res, next) => {
fs.appendFile(
"./index.txt",
`时间: ${new Date()} ---> 请求地址: ${req.url} \n`,
() => next()
);
});
// 配置静态资源
server.use("/static", express.static("./client"));
// 配置接口处理
server.use("/api", allRouter);
// 全局错误处理中间件有一个固定的位置, 一定是在服务器文件的最后
server.use((err, req, res, next) => {
/**
* 当前中间件只是为了将我们的错误 放在一个统一处理的地方
*
* 错误:
* token 过期
* token 不正确
* token 没有传递
* 参数 不够
* 参数 传递的不正确
* ......
*
* 我们可以给这些预估的错误 约定一个编号
* 将来在其他位置的时候遇到了某一个错误
* 我们直接将当前的请求跳转到 这个错误处理中间件
* 并且根据错误的编号, 做出不同的反馈
*
* 这里我们和我们项目的所有后端开发人员做一个约定
* 编号:
* token 过期 1
* token 不正确 2
* token 没有传递 3
* 参数 不够 4
* 参数 传递的不正确 5
* ......
*/
if (err === 1) {
res.send({
code: 0,
msg: "token 过期",
});
} else if (err === 2) {
res.send({
code: 0,
msg: "token 不正确",
});
} else if (err === 3) {
res.send({
code: 0,
msg: "您没有传递 token",
});
} else if (err === 4) {
res.send({
code: 0,
msg: "参数不够",
});
} else if (err === 5) {
res.send({
code: 0,
msg: "参数不正确",
});
}
});
// 配置端口号
server.listen(8080, () => console.log("服务器启动成功"));
处理页面 联动全局错误处理中间件
exports.cartListMid = (req, res, next) => {
/**
* 1. 判断用户有没有传递 用户ID, 并且去数据库查询有没有对应的ID
*
* 在 express 框架中, 一个接口的请求报文中的参数, 会被 express 解析到 req.query 中
*
* 但是注意, 只有 get 请求会被解析, post 请求 不会被解析, post 需要我们像以前写原生服务器一样, 自己解析
*/
if (req.query.userid === undefined) return next(4);
next();
};
参数 不够 4
exports.cartAddItemMid = (req, res, next) => {
// 1. 判断用户有没有传递 用户ID 和 商品ID
const { userid, goodsid } = req.query;
if (!userid || !goodsid) return next(4);
next();
};
exports.cartDelItemMid = (req, res, next) => {
// 1. 判断用户有没有传递 用户ID 和 商品ID
const { userid, goodsid } = req.query;
if (!userid || !goodsid) return next(4);
next();
};