极简Node教程-七天从小白变大神(二:中间件是核心)
当我们只引入express时,前述的那些功能都是没有启用的。那么,如何将这些功能添加进来呢?express通过其中间件机制实现了这些功能的管理。每一个中间件对应一个功能,而中间件可以是第三方库,也可以是我们的业务逻辑。以后我们会经常用到express的中间件。下面我们来简单介绍其工作机制:
你可以把一个中间件理解为一个处理函数(从请求产生响应),通过app.use(<中间件名称>)方法将中间件添加到一个列表中。当HTTP请求到达时,Express会依次调用队列中的中间件,它们的功能便会依次执行,直到某个中间件返回了HTTP响应为止。
---- 以上来自互联网
上集回顾
核心归纳(重要的务必看三遍)
- 中间件是一种功能的封装方式,具体来说就是封装在程序上处理HTTP请求的功能。
- 中间件是在管道中执行的。你可以想象一个送水的真实管道。水从一端泵入,然后在到达目的地之前还会经过各种仪表与阀门。这个比喻很重要的一部分就是顺序问题,你把压力表放在阀门之前和之后效果是不同的。
- 在管道最后面我们会放一个来处理和前面任何路由都不匹配的请求。也就是错误处理中间件一般返回状态吗404.
- 最最重要的就是next()的调用,如果一个中间件你不调用next()那么请求就不会传递出去因为已经被终止了。
favicon的处理
favicon是一个网站的图标,很多浏览器都支持这个功能。浏览器获取通过一个约定好的地址去获取该favicon,并将icon放在地址的前面作为标识。现在再访问一下 http://localhost:3000/ ,看看最上面网站名称前面是不是有一个空白文件的favicon。现在让我们来替换掉它。
首先还是添加依赖npm install serve-favicon --save,然后在server.js中添加以下代码:
var favicon = require('serve-favicon');
app.use(favicon(__dirname + '/favicon.ico'));
然后在项目根目录下面添加一个facicon.ico,这个图标文件可以自己去制作或者去素材网站上寻找.
然后重启服务器,浏览器输入网址:
http://localhost:3000/favicon.ico
就能看到你的网站图标了
自己编写中间件(当然要靠自我奋斗,同时呢...)
通用中间件
我们来写一个通用的可以处理任何请求的中间件,编写中间件其实可以粗浅的理解为以下结构:
app.use(xxx()); // xxx()可以是个匿名函数也可以是第三方中间件那样:
app.use(bodyParser()) //
下面我们写一个打印请求时间的中间件(匿名结构):
app.use(function (req, res, next) { console.log('Time:',
Date.now()); next();});
把上面这个中间件放在server.js 引用模块后的最上方,它就可以第一时间上(各种意义)打印请求时间了,现在重启服务器,重载网页就能在命令行看到请求的时间,不出意外应该有两次吧?,至于为什么,交给聪明的读者吧!
挂载中间件
挂载可以从以下例子理解:
// 挂载至 /user/:id 的中间件,任何指向 /user/:id 的请求都会执行它
app.use('/user/:id', function (req, res, next){
console.log('Request Type:', req.method);
next();});
也就是说只有请求开头user/:id 才会被这个中间件处理,如果不是则会被忽略。
此外上述的req.method是指请求的方式例如:get,post,put,delete
现在把这个中间件添加到第一个中间件下面,然后重启服务器,浏览器输入:
localhost:3000/user/5
虽然页面应该没什么反应,但是命令行会有比较满意的答复。
中间件与模块引入
在谈到这个问题之前,首先必须了解NodeJS的exports引入机制:
我们在routes目录下新建一个文件导出一个用来计算汇率兑换的函数:
// toUSD.js
var rate = 6.4;
export.toUSD = function(count){
return count * rate;
}
保存以后,我们在server.js引用其:
var toUSD = require('./routes/toUSD'); // 可以省略js后缀
console.log(toUSD(100)); // return 640
我们干了什么呢?
我们把计算汇率的函数引用到入口文件这里,然后调用,没有暴露出rate的值,这样符合开闭原则。
如果一个函数你不想暴露里面的细节,而且想多次复用,那么可以采用以上的方式。
那么我们怎么结合模块与中间件呢?
必须清楚的了解中间件是一个函数,而这个中间件是一个函数。
比如我们又有一个模块叫做:
// ./routes/foo.js
module.exports = function(req,res,next){
if(Math.random() > 0.5) next();
res.send('the random num less than 0.5')
}
如果随机数大于0.5我们直接到下一个中间件,跳过响应。不然我们就直接响应请求,后面的中间件将都不会执行。
现在在server.js引入它:
//var foo = require('./routes/foo.js');
// app.use(foo())
或者简单粗暴:
app.use(require('./routes/foo.js'));
但是这样写,弊端就是随着项目不断的扩大,函数数量及文件数量会极具的增加,这样会使我们的项目看起来非常杂乱。如果你不希望你有非常的require语句..以及二次修改时层峦叠嶂的目录函数的话...
怎么优雅的写中间件呢?(知乎体)
输出一个以中间件为属性的对象。形如下面:
// ./routes/xxx.js
module.exports = {
aaa: function(req,res,next){
// doing sth
},
bbb: function(req,res,next){
//doing sth
}
};
// server.js var xxx = require('./routes/xxx.js'); app.use(xxx.aaa); app.use(xxx.bbb);
谢邀,...........
这样我们完美优雅的解决了这个问题
你为什么写中间件这么熟练啊????? 你写过多少次啊???
小结
中间件是Express的核心,路由处理是Express的看家本领,两者都要好好掌握,首先把官方教程批判一番方为正道。
作者:颜卿今天Coding了吗
链接:https://www.jianshu.com/p/aa31761deae3
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
极简Node教程-七天从小白变大神(二:中间件是核心)的更多相关文章
- 极简Node教程-七天从小白变大神(一:你需要Express)
如果说用一句话来概括Node那就是:它开启了JavaScript服务器端语言. Node系列的文章并不会从一开始长篇概论的讲Node的历史,安装,以及其他很琐碎的事情.只会专门介绍关于Node或者准确 ...
- mui初级入门教程(四)— 再谈webview,从小白变“大神”!
文章来源:小青年原创发布时间:2016-06-05关键词:mui,html5+,webview转载需标注本文原始地址: http://zhaomenghuan.github.io/#!/blog/20 ...
- 【同行说技术】Python程序员小白变大神必读资料汇总( 三)
在文章<Python开发.调试.爬虫类工具大全>里面向大家总结了各种实用工具和爬虫技术,今天小编收集了5篇带有实例干货的资料,赶紧来看看吧!另外,喜欢写博客的博主可以申请加工程师博主交流群 ...
- 极简 Node.js 入门 - Node.js 是什么、性能有优势?
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 极简 Node.js 入门 - 1.2 模块系统
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 极简 Node.js 入门 - 1.3 调试
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 极简 Node.js 入门 - 1.4 NPM & package.json
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 极简 Node.js 入门 - 2.1 Path
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 极简 Node.js 入门 - 2.2 事件
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
随机推荐
- eCharts图表(polar极坐标图)
极坐标图 HTML: <div id="eChart"></div> css: #eChart{ width:500px; height:500px; } ...
- Oracle SQL Developer-3.2.20.09.87 Windows 10启动问题处理&配置
用了好多年的工具,准备在笔记本上使用时启动不了,但在办公室PC上可以正常使用.两者电脑OS都一样,一个是全新安装.一个是从Windows 7升级而来.下载了最新版发现版本到17了,Oracle刷版本号 ...
- 【C++】【MFC】创建新的线程函数
DWORD WINAPI MyThreadProc (LPVOID lpParam){ somestruct* pN = (somestruct*)lpParam; // 将参数转为你的类型 ... ...
- LeetCode Move Zeroes (简单题)
题意: 给定一个整型数组nums,要求将其中所有的0移动到末尾,并维护所有非0整数的相对位置不变. 思路: 扫一遍,两个指针维护0与非0的交界,将非0的数向前赋值就行了. C++ class Solu ...
- fpga 状态机 检测1011序列
1011 可以使用4个状态:s0,s1,s2,s3. 即:(1)s0有0或1两个状态,当s0位0时,进入s0状态,自身打圈.为1那么进入下个状态s1来检测0. (2)s1有0或1两种情况,s1为1时s ...
- xtrabackup支持的engine
xtrabackup支持的engine 1.InnoDB/XtraDB Hot backup 2.MyISAM with read-lock 3.Archive,CSV with read-l ...
- 【BZOJ1076】[SCOI2008] 奖励关(状压DP)
点此看题面 大致题意:总共有\(n\)个宝物和\(k\)个回合,每个回合系统将随机抛出一个宝物(抛出每个宝物的概率皆为\(1/n\)),吃掉一个宝物可以获得一定的积分(积分可能为负),而吃掉某个宝物有 ...
- 安装CentOS6.9虚拟机
安装CentOS6.9 之前在学习项目时,都是用的按键好的虚拟机.这次自己也尝试搭建一下.(虽然也是google的) 首先大部分过程都是参考https://blog.csdn.net/pengpeng ...
- 使用POI解析Excel文件
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能. 下载开发包: 解压上面的zip文件: 在项目中引入 ...
- Jquery中的CheckBox、RadioButton、DropDownList的取值赋值实现代码
随着Jquery的作用越来越大,使用的朋友也越来越多.在Web中,由于CheckBox. Radiobutton . DropDownList等控件使用的频率比较高,就关系到这些控件在Jquery中的 ...