当前位置: 首页 > news >正文

网站开发的成品石家庄网站建设培训

网站开发的成品,石家庄网站建设培训,wordpress页头图片比例,如何自己做网站赚钱上一节实现了 express 的中间件,这一节来实现错误处理中间件 执行某一步出错了,统一规定调用 next 传递的参数就是错误信息 先看 express 实现的demo const express require("express"); const app express();app.use("/", (re…

上一节实现了 express 的中间件,这一节来实现错误处理中间件

执行某一步出错了,统一规定调用 next 传递的参数就是错误信息

先看 express 实现的demo

const express = require("express");
const app = express();app.use("/", (req, res, next) => {console.log("中间件1");// next();next("中间件1出错了");
});app.use("/", (req, res, next) => {console.log("中间件2");next();// next("中间件2出错了");
});app.use("/", (req, res, next) => {console.log("中间件3");next();// next("中间件3出错了");
});app.get("/",(req, res, next) => {console.log("路由1");next();},(req, res, next) => {res.end("出错了 *****");}
);app.listen(3000, () => {console.log(`server start 3000`);console.log(`在线访问地址:http://localhost:3000/`);
});

然后去访问:http://localhost:3000/

在这里插入图片描述

错误处理中间价,里面必须要有 4 个 参数(取函数的长度),放到栈的最底下

app.use((err, req, res, next) => {res.end(err);
})

在这里插入图片描述

下面实现处理逻辑

router/index.js

const url = require("url");
const Route = require("./route");
const Layer = require("./layer");
const methods = require("methods");function Router() {// 维护所有的路由this.stack = [];
}Router.prototype.route = function (path) {// 产生 routelet route = new Route();// 产生 layer 让 layer 跟 route 进行关联let layer = new Layer(path, route.dispatch.bind(route));// 每个路由都具备一个 route 属性,稍后路径匹配到后会调用 route 中的每一层layer.route = route;// 把 layer 放到路由的栈中this.stack.push(layer);return route;
};methods.forEach((method) => {Router.prototype[method] = function (path, handlers) {// 1.用户调用 method 时,需要保存成一个 layer 当道栈中// 2.产生一个 Route 实例和当前的 layer 创造关系// 3.要将 route 的 dispatch 方法存到 layer 上let route = this.route(path);// 让 route 记录用户传入的 handler 并且标记这个 handler 是什么方法route[method](handlers);};
});Router.prototype.use = function (path, ...handlers) {// 默认第一个是路径,后面是一个个的方法,路径可以不传if (typeof path === "function") {handlers.unshift(path);path = "/";}// 如果是多个函数需要循环添加层for (let i = 0; i < handlers.length; i++) {let layer = new Layer(path, handlers[i]);// 中间件不需要 route 属性layer.route = undefined;this.stack.push(layer);}
};Router.prototype.handle = function (req, res, out) {console.log("请求到了");// 需要取出路由系统中 Router 存放的 layer 依次执行const { pathname } = url.parse(req.url);let idx = 0;let next = (err) => {// 遍历完后没有找到就直接走出路由系统if (idx >= this.stack.length) return out();let layer = this.stack[idx++];if (err) {console.log("统一对中间件跟路由错误处理");// 找错误处理中间件if (!layer.route) {// 如果是中间件自己处理layer.handle_error(err, req, res, next);} else {// 路由则跳过,继续携带错误向下执行next(err);}} else {// 需要判断 layer 上的 path 和当前请求路由是否一致,一致就执行 dispatch 方法if (layer.match(pathname)) {// 中间件没有方法可以匹配,不能是错误处理中间件if (!layer.route) {if (layer.handler.length !== 4) {layer.handle_request(req, res, next);} else {next();}} else {// 将遍历路由系统中下一层的方法传入// 加速匹配,如果用户注册过这个类型的方法在去执行if (layer.route.methods[req.method.toLowerCase()]) {layer.handle_request(req, res, next);} else {next();}}} else {next();}}};next();
};module.exports = Router;

layer.js

function Layer(path, handler) {this.path = path;this.handler = handler;
}Layer.prototype.match = function (pathname) {if (this.path === pathname) {return true;}// 如果是中间件,进行中间件的匹配规则if (!this.route) {if (this.path == "/") {return true;}// /aaaa/b 需要 /aaaa/ 才能匹配上return pathname.startsWith(this.path + "/");}return false;
};
Layer.prototype.handle_error = function (err, req, res, next) {if (this.handler.length === 4) {// 调用错误处理中间件return this.handler(err, req, res, next);}next(err); // 普通的中间件
};
Layer.prototype.handle_request = function (req, res, next) {this.handler(req, res, next);
};
module.exports = Layer;

route.js

const Layer = require("./layer");
const methods = require("methods");function Route() {this.stack = [];// 用来描述内部存过哪些方法this.methods = {};
}Route.prototype.dispatch = function (req, res, out) {// 稍后调用此方法时,回去栈中拿出对应的 handler 依次执行let idx = 0;console.log("this.stack----->", this.stack);let next = (err) => {// 如果内部迭代的时候出现错误,直接到外层的 stack 中err && out(err);// 遍历完后没有找到就直接走出路由系统if (idx >= this.stack.length) return out();let layer = this.stack[idx++];console.log("dispatch----->", layer.method);if (layer.method === req.method.toLowerCase()) {layer.handle_request(req, res, next);} else {next();}};next();
};
methods.forEach((method) => {Route.prototype[method] = function (handlers) {console.log("handlers----->", handlers);handlers.forEach((handler) => {// 这里的路径没有意义let layer = new Layer("/", handler);layer.method = method;// 做个映射表this.methods[method] = true;this.stack.push(layer);});};
});module.exports = Route;

测试demo

const express = require("./kaimo-express");
const app = express();app.use("/", (req, res, next) => {console.log("中间件1");next();// next("中间件1出错了");
});app.use("/", (req, res, next) => {console.log("中间件2");// next();next("中间件2出错了");
});app.use("/", (req, res, next) => {console.log("中间件3");next();// next("中间件3出错了");
});app.get("/",(req, res, next) => {console.log("路由1");next();},(req, res, next) => {res.end("出错了 *****");}
);// 错误处理中间价
app.use((err, req, res, next) => {console.log("错误处理中间价----->", err);res.end(err);
});app.listen(3000, () => {console.log(`server start 3000`);console.log(`在线访问地址:http://localhost:3000/`);
});

在这里插入图片描述

http://www.hkea.cn/news/369683/

相关文章:

  • 科技型中小企业服务网安徽搜索引擎优化seo
  • 网站建设专家排名邯郸seo营销
  • 做网站一个月20g流量够吗安全又舒适的避孕方法有哪些
  • 扫二维码直接进网站怎么做怎么提交网址让百度收录
  • 柳州建设局网站广告买卖网
  • 做外贸一般上哪些网站google play谷歌商店
  • 泉州手机网站制作如何做企业产品推广
  • 徐州手机网站设计汕头网站建设优化
  • 有没有专业收费做网站优化的百度百科优化排名
  • 常州网站建设哪家便宜江西seo推广软件
  • 如何用pageadmin做网站品牌宣传策略有哪些
  • 网站免费优化软件需要优化的地方
  • 24小时学会网站建设下载厦门百度竞价开户
  • 怎样学做网站网站权重等级
  • 做网站好还是做淘宝好北京seo推广
  • 郑州门户网站建设哪家好网站首页不收录
  • 网站制作营销型哪些网站可以发广告
  • 最新政府网站建设理念广州头条新闻最新
  • 济宁网站建设神华线上推广的三种方式
  • 我要表白网站在线制作如何做网站的教程
  • 福州论坛建站模板策划网络营销活动
  • 网站建设 天津百度市场应用官方app
  • 动态网站制作流程友情链接的定义
  • 企业网站开发方案免费建立一个网站
  • 网站引导页面制作的四个任务名称推广引流的10个渠道
  • 南宁网站建设制作后台网站关键词优化价格
  • 微信小程序商城制作公司宁波seo推广服务
  • 响应式购物网站公司seo是什么意思
  • 360未经证实的网站如何做电商运营方案
  • 网站建设类公司排名营销方案范文100例