express运行原理
一、express底层:http模块
Express框架建立在node.js内置的http模块上。http模块生成服务器的原始代码如下。
var http = require("http");
var app = http.createServer(function(request, response) {
response.writeHead(, {"Content-Type": "text/plain"});
response.end("Hello world!");
});
app.listen(, "localhost");
上面代码的关键是http模块的createServer方法,表示生成一个HTTP服务器实例。该方法接受一个回调函数,该回调函数的参数,分别为代表HTTP请求和HTTP回应的request对象和response对象。
Express框架的核心是对http模块的再包装。上面的代码用Express改写如下。
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello world!');
});
app.listen();
比较两段代码,可以看到它们非常接近。原来是用http.createServer方法新建一个app实例,现在则是用Express的构造方法,生成一个Epress实例。两者的回调函数都是相同的。Express框架等于在http模块之上,加了一个中间层。
二、express中间件
简单说,中间件(middleware)就是处理HTTP请求的函数。它最大的特点就是,一个中间件处理完,再传递给下一个中间件。App实例在运行过程中,会调用一系列的中间件。
每个中间件可以从App实例,接收三个参数,依次为request对象(代表HTTP请求)、response对象(代表HTTP回应),next回调函数(代表下一个中间件)。每个中间件都可以对HTTP请求(request对象)进行加工,并且决定是否调用next方法,将request对象再传给下一个中间件。
一个不进行任何操作、只传递request对象的中间件,就是下面这样。
function uselessMiddleware(req, res, next) {
next();
}
上面代码的next就是下一个中间件。如果它带有参数,则代表抛出一个错误,参数为错误文本。
function uselessMiddleware(req, res, next) {
next('出错了!');
}
抛出错误以后,后面的中间件将不再执行,直到发现一个错误处理函数为止。
在 Node.js Web 开发中,各种模块基本采用这样的中间件格式:
function (req, res, next) {
// req 用于获取请求信息, ServerRequest 的实例
// res 用于响应处理结果, ServerResponse 的实例
// next() 函数用于将当前控制权转交给下一步处理,如果给 next() 传递一个参数时,表示出错信息
}
Express 是基于 Connect 的, Connect 中间件采用了以上的这种格式。 因此,当你要编写一个中间件时,编写一个以上格式的函数即可。
其实跟编写 Express 的路由处理函数是没多大区别的,一些细微的差别是:
- 中间件一般不直接对客户端进行响应,而是对请求进行一些预处理,再传递下去;
- 中间件一般会在路由处理之前执行;
比如:
// 检查用户是否登录中间件,所有需要登录权限的页面都使用此中间件
function checkLogin (req, res, next) {
if (req.session.user) {
next();
} else {
res.redirect('/');
}
}
三、USE方法
use是express注册中间件的方法,它返回一个函数。下面是一个连续调用两个中间件的例子。
var express = require("express");
var http = require("http");
var app = express();
app.use(function(request, response, next) {
console.log("In comes a " + request.method + " to " + request.url);
next();
});
app.use(function(request, response) {
response.writeHead(, { "Content-Type": "text/plain" });
response.end("Hello world!\n");
});
http.createServer(app).listen();
上面代码使用app.use方法,注册了两个中间件。收到HTTP请求后,先调用第一个中间件,在控制台输出一行信息,然后通过next方法,将执行权传给第二个中间件,输出HTTP回应。由于第二个中间件没有调用next方法,所以request对象就不再向后传递了。
use方法内部可以对访问路径进行判断,据此就能实现简单的路由,根据不同的请求网址,返回不同的网页内容。
var express = require("express");
var http = require("http");
var app = express();
app.use(function(request, response, next) {
if (request.url == "/") {
response.writeHead(, { "Content-Type": "text/plain" });
response.end("Welcome to the homepage!\n");
} else {
next();
}
});
app.use(function(request, response, next) {
if (request.url == "/about") {
response.writeHead(, { "Content-Type": "text/plain" });
} else {
next();
}
});
app.use(function(request, response) {
response.writeHead(, { "Content-Type": "text/plain" });
response.end("404 error!\n");
});
http.createServer(app).listen();
上面代码通过request.url属性,判断请求的网址,从而返回不同的内容。注意,app.use方法一共登记了三个中间件,只要请求路径匹配,就不会将执行权交给下一个中间件。因此,最后一个中间件会返回404错误,即前面的中间件都没匹配请求路径,找不到所要请求的资源。
除了在回调函数内部,判断请求的网址,use方法也允许将请求网址写在第一个参数。这代表,只有请求路径匹配这个参数,后面的中间件才会生效。无疑,这样写更加清晰和方便。
app.use('/', someMiddleware);
上面代码表示,只对根目录的请求,调用某个中间件。
因此,上面的代码可以写成下面的样子。
var express = require("express");
var http = require("http");
var app = express();
app.use("/", function(request, response, next) {
response.writeHead(, { "Content-Type": "text/plain" });
response.end("Welcome to the homepage!\n");
});
app.use("/about", function(request, response, next) {
response.writeHead(, { "Content-Type": "text/plain" });
response.end("Welcome to the about page!\n");
});
app.use(function(request, response) {
response.writeHead(, { "Content-Type": "text/plain" });
response.end("404 error!\n");
});
http.createServer(app).listen();
参考资料:
http://javascript.ruanyifeng.com/nodejs/express.html
express运行原理的更多相关文章
- Asp.net WebPages框架运行原理浅析(转)
在Asp.net4和4.5中,新增了WebPages Framework,编写页面代码使用了新的Razor语法,代码更加的简洁和符合Web标准,编写方式更接近于PHP和以前的Asp,和使用 WebFo ...
- ASP.NET的运行原理与运行机制
在Asp.net4和4.5中,新增了WebPages Framework,编写页面代码使用了新的Razor语法,代码更加的简洁和符合Web标准,编写方式更接近于PHP和以前的Asp,和使用WebFor ...
- iBatis.Net的基本情况和运行原理
转载http://www.cnblogs.com/13590/archive/2013/02/27/2934580.html 摘要:介绍iBatis.Net的基本情况和运行原理,运行环境中各参数的配置 ...
- Asp.net WebPages框架运行原理浅析
[来源] 达内 [编辑] 达内 [时间]2012-09-14 在Asp.net4和4.5中,新增了WebPages Framework,编写页面代码使用了新的Razor语法,代码更加的简洁和 ...
- 【原创】分布式之数据库和缓存双写一致性方案解析(三) 前端面试送命题(二)-callback,promise,generator,async-await JS的进阶技巧 前端面试送命题(一)-JS三座大山 Nodejs的运行原理-科普篇 优化设计提高sql类数据库的性能 简单理解token机制
[原创]分布式之数据库和缓存双写一致性方案解析(三) 正文 博主本来觉得,<分布式之数据库和缓存双写一致性方案解析>,一文已经十分清晰.然而这一两天,有人在微信上私聊我,觉得应该要采用 ...
- Serverless 的运行原理与组件架构
本文重点探讨下开发者使用 Serverless 时经常遇到的一些问题,以及如何解决 过去一年,我们和大量 Serverless 用户进行了线上和线下的交流,了解大家的业务场景.对 Serverless ...
- iis6.0与asp.net的运行原理
这几天上网翻阅了不少前辈们的关于iis和asp.net运行原理的博客,学的有点零零散散,花了好长时间做了一个小结(虽然文字不多,但也花了不少时间呢),鄙人不才,难免有理解不道的地方,还望前辈们不吝赐教 ...
- ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件)
ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件) Startup Class 1.Startup Constructor(构造函数) 2.Configure ...
- ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行
ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行 核心框架 ASP.NET Core APP 创建与运行 总结 之前两篇文章简析.NET Core 以及与 .NET Framew ...
随机推荐
- python unittest 1
今天开始研究python的unittest模块,为我们当前做的项目定制测试方案,包括unittest和自动化流程测试. python的unittest的基本使用方法如下: 1.import uni ...
- spring aop的配置
http://www.cnblogs.com/oumyye/p/4480196.html http://blog.csdn.net/hjm4702192/article/details/1727766 ...
- office转换成pdf
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import j ...
- 在Ubuntu中开启Soft AP功能
在Ubuntu中开启Soft AP功能 1.查看采用的无线网卡是否支持Soft AP: 注意,可以看到有AP字样,表明支持.楼主比较背,在易迅上挑了个销量最高的netcore nw360,结果无法搭建 ...
- POJ1159——Palindrome
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 53647 Accepted: 18522 Desc ...
- graphicsmagick常用命令
显示图像文件详细信息 gm identify a.jpg 1.更改当前目录下.jpg的尺寸大小,并保存于目录.thumb里面 gm mogrify -output-directory .thumbs ...
- 利用Python爆破数据库备份文件
某次测试过程中,发现PHP备份功能代码如下: // 根据时间生成备份文件名 $file_name = 'D' . date('Ymd') . 'T' . date('His'); $sql_file_ ...
- ListView实现多种item布局的方法和注意事项
这篇文章的效果也是大家常见的,各种通讯应用的对话列表都是这种方式,像微信.whatsapp.易信.米聊等.我们这篇文章也权当为回忆,形成简单的笔记.这篇文章参考了2009年Google IO中的< ...
- Linux 下 c 语言 聊天软件
这是我学C语言写的第一个软件,是一个完整的聊天软件,里面包括客户端,和服务器端,可以互现聊天,共享文件,有聊天室等,是一个有TCP和UDP协议的聊天软件,测试过很多次在CENTOS和UBUNTU下都通 ...
- 关于CreateProcess函数一些经验
TCHAR szCmdLine[]={TEXT("E:\\CPL-server\\其他工具\\restartSrv\\bin\\opensavepath.exe")}; TCHAR ...