首页 > 代码库 > node.js框架 express

node.js框架 express

express是在node.js的基础上,拓展出的一个简洁实用的框架结构,运用这个东西,我们可以更方便的处理很多的事情。只要上手了,那就是个贝多芬!

一般安装express有几种方法。

第一,使用npm安装,cmd中输入npm install express -g,这个-g是全局安装,也就是安装在被你用"config set global"设置的文件夹里,需要注意的是,安装完了以后,需要改变环境变量以及其路径来指向你的安装目录。

第二,复制粘贴。(……废话!)不过这样的存在安全性问题,因为在复制粘贴的过程中,可能会有数据丢失之类的情况出现。

最后,值得注意的是,一旦在你的nodejs中存在了一个文件夹里面放置了express框架,而且他被你引用过,那么无论你怎么挽救也是无用的……要么把它删除,要么把它覆盖。

express()

创建一个express应用程序

相当于new一个对象,但是还能少写三个字母,将express存入变量app中,从此app翻身做主人!

1
2
3
4
5
6
7
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

这个方法主要运用于设置端口,或者设置文件夹存放,其他用途似乎比较少见

1
2
app.set( ‘title‘ , ‘My Site‘ );
app.get( ‘title‘ ); // => "My Site"

app.get(name)

获取设置项 name 的值

1
2
app.get( ‘title‘ ); // => undefinedapp.set(‘title‘, ‘My Site‘);
app.get( ‘title‘ ); // => "My Site"

app.enable(name)

将设置项 name 的值设为 true.

1
2
app.enable( ‘trust proxy‘ );
app.get( ‘trust proxy‘ ); // => true

app.disable(name)

将设置项 name 的值设为 false.

1
2
app.disable( ‘trust proxy‘ );
app.get( ‘trust proxy‘ ); // => false

app.enabled(name)

检查设置项 name 是否已启用

1
2
app.enabled( ‘trust proxy‘ ); // => falseapp.enable(‘trust proxy‘);
app.enabled( ‘trust proxy‘ ); // => true

app.disabled(name)

检查设置项 name 是否已禁用

1
2
app.disabled( ‘trust proxy‘ ); // => trueapp.enable(‘trust proxy‘)
app.disabled( ‘trust proxy‘ ); // => false

app.use([path], function)

这里有一个实际应用场景,常见的一个应用是使用./public提供静态文件服务,用 express.static() 中间件:

这里path是使用了默认的"/",express.static()保存了资源存放的文件名,__dirname是规定的全局变量,表示开发期间,该行代码所在的目录(其实就是相当于当前文件夹)

1
2
3
4
// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express. static (__dirname + ‘/public‘ ));

如果你想把所有的静态文件路径都前缀"/static", 你可以使用“挂载”功能。如果req.url 不包含这个前缀, 挂载过的中间件不会执行。当function被执行的时候,这个参数不会被传递。这个只会影响这个函数,后面的中间件里得到的 req.url里将会包含"/static"

1
2
3
4
// GET /static/javascripts/jquery.js
// GET /static/style.css
// GET /static/favicon.ico
app.use( ‘/static‘ , express. static (__dirname + ‘/public‘ ));

使用 app.use() “定义的”中间件的顺序非常重要,它们将会顺序执行,use的先后顺序决定了中间件的优先级。比如说通常 express.logger() 是最先使用的一个组件,纪录每一个请求

1
2
3
4
5
app.use(express.logger());
app.use(express. static (__dirname + ‘/public‘ ));
app.use( function (req, res){
   res.send( ‘Hello‘ );
});

如果你想忽略请求静态文件的纪录,但是对于在 logger()之后定义的路由和中间件想继续纪录,只需要简单的把static() 移到前面就行了:

1
2
3
4
5
app.use(express. static (__dirname + ‘/public‘ ));
app.use(express.logger());
app.use( function (req, res){
   res.send( ‘Hello‘ );
});

另一个现实的例子,有可能从多个目录提供静态文件服务,下面的例子中会优先从"./public"目录取文件

1
2
3
app.use(express. static (__dirname + ‘/public‘ ));
app.use(express. static (__dirname + ‘/files‘ ));
app.use(express. static (__dirname + ‘/uploads‘ ));

app.engine(ext, callback)

注册模板引擎的 callback 用来处理ext扩展名的文件默认情况下, 根据文件扩展名require() 对应的模板引擎。比如你想渲染一个 "foo.jade" 文件,Express会在内部执行下面的代码,然后会缓存require(),这样就可以提高后面操作的性能

1
app.engine( ‘jade‘ , require( ‘jade‘ ).__express);

那些没有提供 .__express 的或者你想渲染一个文件的扩展名与模板引擎默认的不一致的时候,也可以用这个方法。比如你想用EJS模板引擎来处理 ".html" 后缀的文件:

1
app.engine( ‘html‘ , require( ‘ejs‘ ).renderFile);

这个例子中EJS提供了一个.renderFile() 方法和Express预期的格式: (path, options, callback)一致, 可以在内部给这个方法取一个别名ejs.__express,这样你就可以使用".ejs" 扩展而不需要做任何改动

有些模板引擎没有遵循这种转换, 这里有一个小项目consolidate.js 专门把所有的node流行的模板引擎进行了包装,这样它们在Express内部看起来就一样了。

1
2
3
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).

1
2
3
4
5
6
7
8
9
10
11
12
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"参数例子行为的回调函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
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()是一致的

1
2
var express = require( ‘express‘ ); var app = express();
app.listen(3000);

express()返回的app实际上是一个JavaScriptFunction,它被设计为传给node的http servers作为处理请求的回调函数。因为app不是从HTTP或者HTTPS继承来的,它只是一个简单的回调函数,你可以以同一份代码同时处理HTTP and HTTPS 版本的服务。

1
2
3
4
5
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,可以使用上面的代码

1
2
3
4
app.listen = function (){
     var server = http.createServer( this );
     return server.listen.apply(server, arguments);
};