情况
我们想要建立一个“传统的”服务器端
使用Hapi呈现应用程序.
我试图了解如何避免返回“原始”400
Joi验证失败时客户端出错:
我们想拦截这个“电子邮件不允许为空”验证错误并将其显示在html模板中返回给客户端,
而不是简单地返回400错误.
@AdriVanHoudt告知我们应该:
“Look at failAction under 07001 “
所以我们将failAction:’log’添加到/ register路由处理程序:
{ method: '*',path: '/register',config: { validate: { payload : register_fields,failAction: 'log' } },handler: register_handler }
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!'); }
我期待在终端/控制台中看到错误
但是当我尝试console.log时,处理程序:
- - - - - - - - - - - - - - - - - - - - - undefined - - - - - - - - - - - - - - - - - - - - - undefined
我在GitHub上问过这个问题:https://github.com/hapijs/joi/issues/725
但还没有得到一个很好的例子.
完整代码,如果你有时间帮助:https://github.com/nelsonic/hapi-validation-question
解决方法
1.使用server.ext(‘onPreResponse’…
正如@Clarkie所述,捕获Hapi App中所有错误的一般方法是使用’onPreResponse’.
我们编写了一个Hapi插件,它正是这样做的:https://www.npmjs.com/package/hapi-error
像往常一样,它有:
1.从npm安装plugin:
npm install hapi-error --save
2.在Hapi项目中包含插件
See: 07008 for simple example
3.确保您有一个名为error_template的视图
Note:
hapi-error
plugin expects you are using 07009 (the standard view rendering library for Hapi apps)
which allows you to use Handlebars,Jade,React,etc. for your templates.
您的error_template.html(或error_template.ext error_template.jsx)应该使用它将传递的3个变量:
> errorTitle – Hapi生成的错误磁贴
> statusCode – *发送到客户端的HTTP statusCode,例如:404(未找到)
> errorMessage – 人性化的错误消息
for an example see: 070010
而已!
2.使用failAction
我们添加了failAction,它重用了register_handler
这样,registration-form.html会显示任何输入验证错误消息(直到它提交有效数据)
{ method: '*',failAction: register_handler // register_handler is dual-purpose (see below!) } },handler: register_handler }
register_handler是:
function register_handler(request,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) }) } }
See: 070015 for complete file.
其中extract_validation_error(错误)和return_form_input_values(错误)
是在server.js中定义的辅助函数(但会被拆分为可重用的视图助手),这使我们的处理函数保持精简状态.
当我们提交没有任何必填字段的表单时,我们会看到:
我们也使用https://github.com/chriso/validator.js
缓解Cross Site Scripting
漏洞:
结论
我们觉得重用处理函数作为failAction
将与此路线/操作相关的代码保存在一个位置
而server.ext(‘onPreResponse’…(虽然在初步检查时适当)将引入“钩子”
这可能是一个混乱的来源(一旦一个应用程序有很多这样的钩子……)
#YMMV