express之layer.js
发布日期:2021-05-28 16:24:03
浏览次数:25
分类:技术文章
本文共 3045 字,大约阅读时间需要 10 分钟。
lib/router/layer.jsmodule.exports = Layer;//Layer构造函数,一个Layer可以属于router,也可以属于Route//当调用router的route方法时,Layer作为Route对象的中间层,它的path与创建的Route的path一样,它的handle为Route的dispatch方法//当调用router的use方法时,Layer的handle为use添加的中间件方法,可能是一个router对象、也可能是一个标准的中间件方法//当属于Route时,代表一个使用all、get、post方法添加的路由处理方法,此时Layer是有method的,但是其path为/,可以做方法匹配,但是不做路径匹配function Layer(path, options, fn) { //确保作为构造函数调用 if (!(this instanceof Layer)) { return new Layer(path, options, fn); } debug('new %o', path) var opts = options || {}; //设置处理函数,可能为中间件,此时可能为普通中间件函数、Router对象、express实例的包装函数 //可能为指定http方法的处理函数、Route的dispatch方法 //一个handle只可能处理请求或者err,必须是标准的请求处理函数req、res、next或者标准的错误处理函数err、req、res、next this.handle = fn; //函数名或者匿名函数,因为Router本身就是匿名函数 this.name = fn.name || ''; this.params = undefined; //路径,属于Router时,代表挂载的中间件路径 //属于Route时,为/ this.path = undefined; //正则 this.regexp = pathRegexp(path, this.keys = [], opts); // 快速匹配 //路径是否为*,代表匹配所有路径 this.regexp.fast_star = path === '*' //path为/,代表匹配根路径 this.regexp.fast_slash = path === '/' && opts.end === false}//错误处理函数Layer.prototype.handle_error = function handle_error(error, req, res, next) { //内部处理函数还是handle var fn = this.handle; //函数的参数不是四个,err、req、res、next,即不是标准的express错误处理函数,继续向下传递 if (fn.length !== 4) { return next(error); } try { fn(error, req, res, next); } catch (err) { next(err); }};//请求处理函数Layer.prototype.handle_request = function handle(req, res, next) { var fn = this.handle; //如果参数多于三个,说明不是标准的请求处理函数 if (fn.length > 3) { return next(); } try { fn(req, res, next); } catch (err) { next(err); }};//Layer是否匹配指定路径Layer.prototype.match = function match(path) { var match if (path != null) { //当Layer属于一个Route时,path为/, /肯定匹配所有路径开始的/,因为每个路径开始都是/ if (this.regexp.fast_slash) { //此时路径参数为空,因为Layer匹配部分只有一个/其他部分另外处理 this.params = {} //path为空 this.path = '' return true } //当Layer路径为*代表匹配所有路由,此时匹配部分为参数path的全部 if (this.regexp.fast_star) { //路径参数 this.params = {'0': decode_param(path)} //路径 this.path = path return true } //其他普通情况,执行正则匹配 match = this.regexp.exec(path) } //没有匹配项 if (!match) { //路径与路径参数都为空 this.params = undefined; this.path = undefined; return false; } //路径为第一个匹配项 this.params = {}; this.path = match[0] //路径参数 var keys = this.keys; var params = this.params; //遍历匹配结果数组,从下标1开始,因为0已经给了path for (var i = 1; i < match.length; i++) { var key = keys[i - 1]; //获取路径参数名 var prop = key.name; //解码匹配项为路径参数值 var val = decode_param(match[i]) if (val !== undefined || !(hasOwnProperty.call(params, prop))) { //将路径参数赋值给params属性 params[prop] = val; } } return true;};//解码路径参数值function decode_param(val) { //不是字符串或者长度为0,直接返回 if (typeof val !== 'string' || val.length === 0) { return val; } try { //url组件解码 return decodeURIComponent(val); } catch (err) { if (err instanceof URIError) { err.message = 'Failed to decode param \'' + val + '\''; err.status = err.statusCode = 400; } throw err; }}
转载地址:https://blog.csdn.net/qq_27868061/article/details/79275747 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年01月16日 13时53分04秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
关于最小生成树中的kruskal算法中判断两个点是否在同一个连通分量的方法总结...
2019-06-23
开篇,博客的申请理由
2019-06-23
Servlet 技术全总结 (已完成,不定期增加内容)
2019-06-23
[JSOI2008]星球大战starwar BZOJ1015
2019-06-23
CountDownLatch与thread-join()的区别
2019-06-23
linux下MySQL安装登录及操作
2019-06-23
centos 7 部署LDAP服务
2019-06-23
揭秘马云帝国内幕:马云的野心有多大
2019-06-23
topcoder srm 680 div1
2019-06-23
算法专题(1)-信息学基本解题流程!
2019-06-23
iOS项目分层
2019-06-23
UML关系图
2019-06-23
一个action读取另一个action里的session
2019-06-23
IntelliJ IDEA 注册码
2019-06-23
linux 上面配置apache2的虚拟目录
2019-06-23
Linux学习总结 (未完待续...)
2019-06-23
NoSQL数据库探讨 - 为什么要用非关系数据库?
2019-06-23
String字符串的截取
2019-06-23
Spring MVC简单原理
2019-06-23
DynamoDB Local for Desktop Development
2019-06-23