HTTP方法
在CSSer前面的文章中我们已经接触过app.get()多次了,同时Express也提供了对其它HTTP动作的封装,如app.post(), app.del()等。
对于POST最常见的例子,就是当我们提交一个表单时,下面我们在HTML中将表单的method特性设置为“post”,然后需要在服务端定义对该表单提交的路由控制。
<form method="post" action="/"> <input type="text" name="user[name]" /> <input type="text" name="user[email]" /> <input type="submit" value="Submit" data-description="csser.com" /> </form>
默认情况下Express并不知道该如何处理该请求体,因此我们需要增加bodyParser中间件,用于分析application/x-www-form-urlencoded和application/json请求体,并把变量存入req.body。我们可以像下面的样子来“使用”中间件:
app.use(express.bodyParser());
接下来下面的路由就可以访问req.body.user对象了,该对象包含客户端提交的name和email属性。
app.post('/', function(req, res){ console.log(req.body.user); res.redirect('back'); });
要在表单中使用PUT的HTTP方法,我们可以利用名为_method的隐藏表单域,它能改变HTTP方法。而在服务端,我们首先需要利用methodOverride中间件,把它放在bodyParser中间件下方,从而可以利用包含表单值的req.body。
app.use(express.bodyParser()); app.use(express.methodOverride());
之所以需要这样做,是因为这些处理并不总是默认进行的,原因很简单,因为这些对Express的整体功能来说并不是必需的,依据应用的具体需求,你并不一定需要这些功能,如果客户端直接支持PUT和DELETE方法也可以被直接访问到,同时methodOverride为表单提供了强大的解决方案,下面我们展示下PUT的使用:
<form method="post" action="/"> <input type="hidden" name="_method" value="put" /> <input type="text" name="user[name]" /> <input type="text" name="user[email]" /> <input type="submit" value="Submit" /> </form> app.put('/', function(){ console.log(req.body.user); res.redirect('back'); });
错误处理
Express提供了app.error()方法来接收路由或传入next(err)的异常,下面的示例为不同的页面提供专门的NotFound异常服务:
function NotFound(msg){ this.name = 'NotFound in csser.com'; Error.call(this, msg); Error.captureStackTrace(this, arguments.callee); } NotFound.prototype.__proto__ = Error.prototype; app.get('/404', function(req, res){ throw new NotFound; }); app.get('/500', function(req, res){ throw new Error('keyboard cat!'); });
像下面一样,我们可以多次调用app.error(),这里我们检查如果是NotFound实例就显示404页面,否则将其传入下一个错误处理。
注意这些处理可以定义在任何地方,它们可以放在路由可以listen()之处。这也允许在configure()块内做定义,于是我们就可以以不同的基于环境的方式处理异常。
app.error(function(err, req, res, next){ if (err instanceof NotFound) { res.render('404.jade'); } else { next(err); } });
下面的演示我们假设所有错误都为500错误,但你可以根据喜好选择。例如当node在处理文件系统调用时,就有可能接收到这样的错误对象,其ENOENT的error.code为“no such file or directory”,这时我们可以在错误处理函数中进行处理然后显示特定的页面给用户。
app.error(function(err, req, res){ res.render('500.jade', { error: err }); });
我们的应用也可以利用Connect errorHandler中间件来汇报异常信息。例如我们想在“开发”环境输出异常到stderr:
app.use(express.errorHandler({ dumpExceptions: true }));
同时在开发期间我们想用好看的HTML页面显示异常信息时,可以设置showStack的值为true:
app.use(express.errorHandler({ showStack: true, dumpExceptions: true }));
如果请求头支持application/json,errorHandler中间件也能以json方式做出响应,这对依赖于客户端Javascript的应用开发很有益处。