Express是一个简洁而灵活的 node.js Web套用框架, 提供一系列强大特性帮助你创建各种Web套用。
基本介绍
- 外文名:expressjs
- 属于:node.js Web套用框架
- 功能:创建各种Web套用
- 性质:已有的特性进行二次抽象
性能
Express不是对node.js 已有的特性进行二次抽象,我们只是在它之上扩展了Web套用所需的功能。
编程接口
express()
创建一个express应用程式
var express = require('express');var app = express();app.get('/', function(req, res){ res.send('hello world');});app.listen(3000);
app.set(name, value)
将设定项 name 的值设为 value
app.set('title', 'My Site');app.get('title');// => "My Site"
app.get(name)
获取设定项 name 的值
app.get('title');// => undefinedapp.set('title', 'My Site');app.get('title');// => "My Site"
app.enable(name)
将设定项 name 的值设为 true.
app.enable('trust proxy');app.get('trust proxy');// => true
app.disable(name)
将设定项 name 的值设为 false.
app.disable('trust proxy');app.get('trust proxy');// => false
app.enabled(name)
检查设定项 name 是否已启用
app.enabled('trust proxy');// => falseapp.enable('trust proxy');app.enabled('trust proxy');// => true
app.disabled(name)
检查设定项 name 是否已禁用
app.disabled('trust proxy');// => trueapp.enable('trust proxy');app.disabled('trust proxy');// => false
app.configure([env], callback)
当 env 和 app.get('env')(也就是 process.env.NODE_ENV) 匹配时, 调用callback。保留这个方法是出于历史原因,后面列出的if语句的代码其实更加高效、直接。使用app.set()配合其它一些配置方法后,没有必要再使用这个方法。
// 所有环境app.configure(function(){ app.set('title', 'My Application'); })// 开发环境app.configure('development', function(){ app.set('db uri', 'localhost/dev'); })// 只用于生产环境app.configure('production', function(){ app.set('db uri', 'n.n.n.n/prod'); })
更高效且直接的代码如下:
// 所有环境app.set('title', 'My Application');// 只用于开发环境if ('development' == app.get('env')) { app.set('db uri', 'localhost/dev'); } // 只用于生产环境 if ('production' == app.get('env')) { app.set('db uri', 'n.n.n.n/prod');}
app.use([path], function)
使用中间件 function,可选参数path默认为"/"。
var express = require('express');var app = express();// 一个简单的 loggerapp.use(function(req, res, next){ console.log('%s %s', req.method, req.url); next();});// 回响app.use(function(req, res, next){ res.send('Hello World');});app.listen(3000);
挂载的路径不会在req里出现,对中间件 function不可见,这意味着你在function的?>回调参数req里找不到path。这幺设计的为了让间件可以在不需要更改代码就在任意"前缀"路径下执行
这里有一个实际套用场景,常见的一个套用是使用./public提供静态档案服务,用 express.static() 中间件:
// GET /javascripts/jquery.js// GET /style.css// GET /favicon.icoapp.use(express.static(__dirname + '/public'));
如果你想把所有的静态档案路径都前缀"/static", 你可以使用“挂载”功能。如果req.url 不包含这个前缀, 挂载过的中间件不会执行。当function被执行的时候,这个参数不会被传递。这个只会影响这个函式,后面的中间件里得到的 req.url里将会包含"/static"
// GET /static/javascripts/jquery.js// GET /static/style.css// GET /static/favicon.icoapp.use('/static', express.static(__dirname + '/public'));
使用 app.use() “定义的”中间件的顺序非常重要,它们将会顺序执行,use的先后顺序决定了中间件的优先权。比如说通常 express.logger() 是最先使用的一个组件,纪录每一个请求
app.use(express.logger());app.use(express.static(__dirname + '/public'));app.use(function(req, res){ res.send('Hello');});
如果你想忽略请求静态档案的纪录,但是对于在 logger()之后定义的路由和中间件想继续纪录,只需要简单的把static() 移到前面就行了:
app.use(express.static(__dirname + '/public'));app.use(express.logger());app.use(function(req, res){ res.send('Hello');});
另一个现实的例子,有可能从多个目录提供静态档案服务,下面的例子中会优先从"./public"目录取档案
app.use(express.static(__dirname + '/public'));app.use(express.static(__dirname + '/files'));app.use(express.static(__dirname + '/uploads'));
settings
下面的内建的可以改变Express行为的设定
- env 运行时环境,默认为 process.env.NODE_ENV 或者 "development"
- trust proxy 激活反向代理,默认未激活状态
- jsonp callback name 修改默认?callback=的jsonp回调的名字
- json replacer JSON replacer 替换时的回调, 默认为null
- json spaces JSON 回响的空格数量,开发环境下是2 , 生产环境是0
- case sensitive routing 路由的大小写敏感, 默认是关闭状态, "/Foo" 和"/foo" 是一样的
- strict routing 路由的严格格式, 默认情况下 "/foo" 和 "/foo/" 是被同样对待的
- view cache 模板快取,在生产环境中是默认开启的
- view engine 模板引擎
- views 模板的目录
app.engine(ext, callback)
注册模板引擎的 callback 用来处理ext扩展名的档案默认情况下, 根据档案扩展名require() 对应的模板引擎。比如你想渲染一个 "foo.jade" 档案,Express会在内部执行下面的代码,然后会快取require(),这样就可以提高后面操作的性能
app.engine('jade', require('jade').__express);
那些没有提供 .__express 的或者你想渲染一个档案的扩展名与模板引擎默认的不一致的时候,也可以用这个方法。比如你想用EJS模板引擎来处理 ".html" 后缀的档案:
app.engine('html', require('ejs').renderFile);
这个例子中EJS提供了一个.renderFile() 方法和Express预期的格式: (path, options, callback)一致, 可以在内部给这个方法取一个别名ejs.__express,这样你就可以使用".ejs" 扩展而不需要做任何改动
有些模板引擎没有遵循这种转换, 这里有一个小项目consolidate.js 专门把所有的node流行的模板引擎进行了包装,这样它们在Express内部看起来就一样了。
var engines = require('consolidate');app.engine('haml', engines.haml);app.engine('html', engines.hogan);
app.param([name], callback)
路由参数的处理逻辑。比如当 :user 出现在一个路由路径中,你也许会自动载入载入用户的逻辑,并把它放置到 req.user , 或者校验一下输入的参数是否正确。
下面的代码片段展示了callback很像中间件,但是在参数里多加了一个值,这里名为id.它会尝试载入用户信息,然后赋值给req.user, 否则就传递错误next(err).
app.param('user', function(req, res, next, id){ User.find(id, function(err, user){ if (err) { next(err); } else if (user) { req.user = user; next(); } else { next(new Error('failed to load user')); } });});
另外你也可以只传一个callback, 这样你就有机会改变 app.param() API.比如express-params定义了下面的回调,这个允许你使用一个给定的正则去限制参数。
下面的这个例子有一点点高级,检查如果第二个参数是一个正则,返回一个很像上面的"user"参数例子行为的回调函式。
app.param(function(name, fn){ if (fn instanceof RegExp) { return function(req, res, next, val){ var captures; if (captures = fn.exec(String(val))) { req.params[name] = captures; next(); } else { next('route'); } } }});
这个函式现在可以非常有效的用来校验参数,或者提供正则捕获后的分组。
app.listen()
在给定的主机和连线埠上监听请求,这个和node的文档http.Server#listen()是一致的
var express = require('express');var app = express();app.listen(3000);
express()返回的app实际上是一个JavaScriptFunction,它被设计为传给node的http servers作为处理请求的回调函式。因为app不是从HTTP或者HTTPS继承来的,它只是一个简单的回调函式,你可以以同一份代码同时处理HTTP and HTTPS 版本的服务。
var express = require('express');var https = require('https');var http = require('http');var app = express();http.createServer(app).listen(80);https.createServer(options, app).listen(443);
app.listen() 方法只是一个快捷方法,如果你想使用HTTPS,或者同时提供HTTP和HTTPS,可以使用上面的代码
app.listen = function(){ var server = http.createServer(this); return server.listen.apply(server, arguments);};
版本
Express当前版本:v.4.12.3