Closed FrankKai closed 6 years ago
Connect是一个使用插件进行扩展HTTP 服务器的Nodejs框架,通常我们将这些插件称作"中间件"。
var connect = require('connect');
var http = require('http');
var app = connect();
// 压缩/解压 然后输出响应
var compression = require('compression');
app.use(compression());
// 在浏览器cookie中存储session状态
var cookieSession = require('cookie-session');
app.use(cookieSession({
keys: ['secret1', 'secret2']
}));
// 解析编码请求体到req.body
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
// 响应所有请求
app.use(function(req, res){
res.end('Hello from Connect!\n');
});
// 创建node.js http 服务器并监听端口
http.createServer(app).listen(3000);
Connect 是一个简单的框架,它主要负责粘合各种中间件去处理请求。
$ npm install connect
主组件是一个Connect应用。这将存储所有的中间件,并且这个主组件本身也是一个函数。
var app = connect();
Connect的核心是"使用"中间件。中间件被添加到"stack"中,栈里传入请求并且逐一执行每个中间件,直到某一个中间件内部不再调用next()
。
app.use(function middleware1(req, res, next) {
// middleware 1
next();
});
app.use(function middleware2(req, res, next) {
// middleware 2
next();
});
.use()
方法也接收一个额外的可选的路径字符串,这个字符串与输入的请求url的开始处匹配。从而实现下面这样基本的路由:
app.use('/foo', function fooMiddleware(req, res, next) {
// req.url的开头是 "/foo"
next();
});
app.use('/bar', function barMiddleware(req, res, next) {
// req.url的开头是"/bar"
next();
});
有一些特殊的异常处理中间件。这种类型的中间件通常会接收4个参数。当中间件传递一个error到next时,应用将继续寻找在当前中间件之后已声明的异常中间件并且调用它,跳过其他的之前的异常中间件和之后的非异常中间件。
// 通常的中间件
app.use(function (req, res, next) {
// 我有一个异常
next(new Error('boom!'));
});
// 发生在中间件中的为error定义的异常中间件
// 在这里定义了onerror异常中间件函数
app.use(function onerror(err, req, res, next) {
// 一个错误发生了!
});
最后一步实质上是在一个服务器上使用Connect应用。.listen
方法是一个很方便的启动HTTP服务器的接口(),实质上与你正在运行的Node.js中的http.Server
的listen
方法相同。
var server = app.listen(port);
应用本身仅仅是一个需要传入3个参数的函数,所以它可以传递到Node.js的.createServer()
。
var server = http.createServer(app);
这些中间件和库通常由Connect/Express团队维护:
bodyParser
, json
, and urlencoded
. You may also be interested in:
compress
timeout
cookieParser
cookieSession
csrf
error-handler
session
method-override
logger
response-time
favicon
directory
static
vhost
除cookie-session之外,大多数中间件与Connect 2.x版本的等价接口。
一些之前版本的中间件已经不被Connect/Express团队提供支持,被可选择性的模块所替代,或者被更好地模块替代。可以改用其中一种替代方法:
cookieParser
limit
multipart
query
staticCache
查看 http-framework 提交其他稳定的http库。
Connect API非常简单,足以去创建一个app并且添加一个middleware链。
当connect
模块被引入进来以后,调用函数以后会构建并且返回一个新的应用。
// 引入模块
var connect = require('connect')
// 创建应用
var app = connect()
app自身是一个函数。它其实只是app.handle的别名。
函数调用时将运行middleware栈中的给定的http请求(req)和http响应(res)对象。一个可选的函数out,如果请求或者error不被中间件调用栈处理的话,它会被调用。
启动应用去监听请求。这个方法将在内部新建一个Node.js HTTP服务器并且调用.listen()
方法。
这个一种替代Node.js的原生server.listen()方法,所以请查阅Node.js文档去查阅不同的变体。最常见的签名是app.listen(port)
.
在一个应用程序中使用一个函数,当函数代表一个中间件时。函数将会按照app.use的顺序调用函数去处理每个请求。函数调用主要传入以下3个参数:
app.use(function (req, res, next) {
// req 是 Node.js http请求对象
// res 是 Node.js http响应对象
// next是一个调用下一个中间件的函数
})
除了plan函数,fn参数通常是Node.js HTTP服务器实例或者其他的Connect应用实例。
应用中使用函数,函数指的是中间件。对于URL(req.url
属性)开头相同的每个请求,app.use都会调用相同的中间件函数。route可以有多个路径,而中间件函数有三个参数:
app.use('/foo', function (req, res, next) {
// req 是 Node.js http请求对象
// res 是 Node.js http响应对象
// next是一个调用下一个中间件的函数
})
除了plan函数,fn参数通常是Node.js HTTP服务器实例或者其他的Connect应用实例。
route通常由路径分隔符/和.字符串组成。这意味着给定的/foo/和/foo是相同的,并且将会匹配/foo
, /foo/
, /foo/bar
, and /foo.bar
,但是不会匹配/foobar
route不区分大小写。
为了更加简单地创建中间件,一般写入route未知的路径,当fn被调用后,req.url将会被去除route部分(路径将会被赋值到req.originalUrl变量)
当例如,如果fn在/foo路由中使用, /foo/bar
被请求时,req会生成url属性和originalUrl属性,此时,req.url === '/bar'
和req.originalUrl === '/foo/bar'
。
面试完之后,在《Node.js实战》中了解到Connect中间件框架,对于原理讲的比较清楚,但是了解到这是一个开源框架,更新进度要比书领先,因此我将对其README进行翻译,从而汲取最新版本的Connect框架中的营养。 https://github.com/senchalabs/connect