如何避免在Joivalidation请求时Hapi.js发送400错误

Hapi.jsvalidation与Joi + failAction问题。

情况

我们希望使用Hapi构build一个“ 传统的 服务器端渲染的应用程序。

我试图了解如何避免在Joivalidation失败时将“ 原始400错误返回给客户端:

寄存器的iphone4s-SIM

我们想拦截这个“ 不允许为空的电子邮件validation错误,并将其显示在客户端的html模板中,而不是简单地返回400错误。

@AdriVanHoudtbuild议我们应该:

“看看http://hapijs.com/api#route-options下的failAction”

所以我们添加了failAction: 'log'/registerpath处理器:

 { method: '*', path: '/register', config: { validate: { payload : register_fields, failAction: 'log' } }, handler: register_handler } 

请参阅: server.js中的代码

register_handler是:

 function register_handler(request, reply, source, error) { console.log(request.payload); console.log(' - - - - - - - - - - - - - - - - - - - - -'); console.log(source) console.log(' - - - - - - - - - - - - - - - - - - - - -'); console.log(error) return reply('welcome!'); } 

我期待在terminal/控制台中看到一个错误,但是当我尝试console.log handler

 - - - - - - - - - - - - - - - - - - - - - undefined - - - - - - - - - - - - - - - - - - - - - undefined 

我问了关于GitHub的问题: https : //github.com/hapijs/joi/issues/725,但还没有得到一个 例子的答案。 完整的代码,如果你有时间来帮忙: https : //github.com/nelsonic/hapi-validation-question

两个简单的解决scheme:

1.使用server.ext('onPreResponse' ...

正如@Clarkie指出的那样,在您的Hapi App中捕获所有错误的一般方法是使用'onPreResponse'

我们写了一个Hapi插件,它的确如此: https : //www.npmjs.com/package/hapi-error

像往常一样,它有

构建状态 codecov.io 守则气候 依赖状态 devDependency状态 HitCount

而且可以通过3个简单的步骤定义自己的自定义错误页面。

1.从npm安装插件 :

 npm install hapi-error --save 

2.将该插件包含在您的Hapi项目中

register服务器时join插件:

有关简单示例,请参见/example/server_example.js

3.确保您有一个名为error_template的视图

注意: hapi-error插件期望您使用VisionHapi应用程序的标准视图渲染库 ),它允许您为模板使用Handlebars,Jade,React等。

你的error_template.htmlerror_template.ext error_template.jsx )应该使用它将被传递的3个variables:

  • errorTitle由Hapi生成的错误图块
  • statusCode – *发送到客户端的HTTP statusCode, 例如: 404未find
  • errorMessage人性化的错误信息

例如,请参阅: /example/error_template.html

就是这样

高致病性禽流感发生误差屏

2.使用failAction

构建状态 codecov.io 守则气候 HitCount

我们添加了failAction ,它重新使用register_handler ,使得registration-form.html显示了任何inputvalidation错误消息( 直到它被提交了有效数据

 { method: '*', path: '/register', config: { validate: { payload : register_fields, failAction: register_handler // register_handler is dual-purpose (see below!) } }, handler: register_handler } 

register_handler是:

 function register_handler(request, reply, source, error) { // show the registration form until its submitted correctly if(!request.payload || request.payload && error) { var errors, values; // return empty if not set. if(error && error.data) { // means the handler is dual-purpose errors = extract_validation_error(error); // the error field + message values = return_form_input_values(error); // avoid wiping form data } return reply.view('registration-form', { title : 'Please Register ' + request.server.version, error : errors, // error object used in html template values : values // (escaped) values displayed in form inputs }).code(error ? 400 : 200); // HTTP status code depending on error } else { // once successful, show welcome message! return reply.view('welcome-message', { name : validator.escape(request.payload.name), email : validator.escape(request.payload.email) }) } } 

完整的文件请参见: server.js :57 。

其中extract_validation_error(error)return_form_input_values(error)是在server.js定义的辅助函数( 但是会被分解为可重用的视图助手 ),这使得我们的处理函数变得精简。

当我们提交没有任何必填字段的表单时,我们会看到:

寄存器1of4

寄存器3of4

我们还使用https://github.com/chriso/validator.js来缓解跨站点脚本漏洞:

寄存器下锅1of2

并显示一个成功注册的欢迎消息: REG成功 -  1of2

结论

我们觉得重新使用处理函数作为failAction可以将与这个路由/动作相关的代码保存在一个地方,而server.ext('onPreResponse' ...虽然在初始检查时是合适的 )会引入“ hooks ”是一个混乱的来源( 一旦一个应用程序有很多这样的钩子…

#YMMV

让我们知道您的想法! 通过https://gitter.im/dwyl/chat加入聊天

你应该看看在onPreResponse 扩展点实现一个error handling程序。

request.response中包含的响应可能会被修改(但不会被分配一个新的值)。 要返回不同的响应types(例如,用HTML响应replace错误),请通过回复(响应)返回新响应。 请注意,调用回复(响应)后生成的任何错误都不会被传回onPreResponse扩展方法,以防止无限循环。

一个简单的例子:

 server.ext('onPreResponse', function (request, reply) { if (request.response.statusCode === 400 ){ return reply('summat else'); } return reply.continue(); });