使用 Joi 验证请求时如何避免 Hapi.js 发送 400 错误
How to avoid Hapi.js sending 400 error when Validating Request with Joi
Hapi.js 使用 Joi + failAction
问题进行验证。
情况
我们想构建一个“传统”服务器端-仅
使用 Hapi.
呈现的应用程序
我正在尝试了解如何避免返回“raw”400
当 Joi
验证 失败时客户端出错 :
我们要拦截这个“email not allowed to be empty”validation error并显示在html模板返回给客户端,
而不是简单地返回 400
错误。
@AdriVanHoudt建议我们应该:
"Look at failAction under http://hapijs.com/api#route-options "
因此我们将 failAction: 'log'
添加到 /register
路由处理程序:
{
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 中看到错误
但是当我尝试 console.log
时 handler
:
- - - - - - - - - - - - - - - - - - - - -
undefined
- - - - - - - - - - - - - - - - - - - - -
undefined
我在 GitHub 上问了这个问题:https://github.com/hapijs/joi/issues/725
但还没有得到 good example 的答案。
如果您有时间提供帮助,请提供完整代码:https://github.com/nelsonic/hapi-validation-question
您应该查看 onPreResponse
extension point 中的错误处理程序。
The response contained in request.response may be modified (but not assigned a new value). To return a different response type (for example, replace an error with an HTML response), return a new response via reply(response). Note that any errors generated after reply(response) is called will not be passed back to the onPreResponse
extension method to prevent an infinite loop.
一个简单的例子:
server.ext('onPreResponse', function (request, reply) {
if (request.response.statusCode === 400 ){
return reply('summat else');
}
return reply.continue();
});
有两个简单的解决方案:
1。使用 server.ext('onPreResponse' ...
正如@Clarkie 所指出的,在您的 Hapi 应用程序中捕获 所有 错误的 通用 方法是使用 'onPreResponse'
。
我们写了一个 Hapi 插件,它就是这样做的:https://www.npmjs.com/package/hapi-error
和往常一样:
并允许您通过 3 个简单的步骤定义自己的自定义错误页面。
1。从 npm:
安装 plugin
npm install hapi-error --save
2。在你的 Hapi 项目中包含插件
当您 register
您的服务器时包含插件:
See: /example/server_example.js for simple example
3。确保您有一个名为 error_template
的视图
Note: hapi-error
plugin expects you are using Vision
(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生成的错误tile
statusCode
- *HTTP statusCode 发送给客户端例如:404
(未找到)
errorMessage
- human-friendly 错误信息
for an example see: /example/error_template.html
就是这样!
2。使用 failAction
我们添加了 failAction
其中 re-uses register_handler
以便 registration-form.html
显示任何输入验证错误消息(直到提交有效数据)
{
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)
})
}
}
See: server.js:57 for complete file.
其中 extract_validation_error(error)
和 return_form_input_values(error)
是在 server.js
中定义的辅助函数( 但会拆分成 re-useable 视图助手 ),这使我们的处理函数保持精简。
当我们提交没有任何必填字段的表单时,我们看到:
我们也用https://github.com/chriso/validator.js
减轻 Cross Site Scripting
漏洞:
并在注册成功时显示欢迎信息:
结论
我们认为 re-using 处理函数作为 failAction
将与此 route/action 相关的代码保存在一个地方
而 server.ext('onPreResponse' ...
(虽然适合初始检查)将引入“hooks”
可能会造成混淆(一旦一个应用有很多这样的钩子...)
#YMMV
Hapi.js 使用 Joi + failAction
问题进行验证。
情况
我们想构建一个“传统”服务器端-仅 使用 Hapi.
呈现的应用程序我正在尝试了解如何避免返回“raw”400
当 Joi
验证 失败时客户端出错 :
我们要拦截这个“email not allowed to be empty”validation error并显示在html模板返回给客户端,
而不是简单地返回 400
错误。
@AdriVanHoudt建议我们应该:
"Look at failAction under http://hapijs.com/api#route-options "
因此我们将 failAction: 'log'
添加到 /register
路由处理程序:
{
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 中看到错误
但是当我尝试 console.log
时 handler
:
- - - - - - - - - - - - - - - - - - - - -
undefined
- - - - - - - - - - - - - - - - - - - - -
undefined
我在 GitHub 上问了这个问题:https://github.com/hapijs/joi/issues/725 但还没有得到 good example 的答案。 如果您有时间提供帮助,请提供完整代码:https://github.com/nelsonic/hapi-validation-question
您应该查看 onPreResponse
extension point 中的错误处理程序。
The response contained in request.response may be modified (but not assigned a new value). To return a different response type (for example, replace an error with an HTML response), return a new response via reply(response). Note that any errors generated after reply(response) is called will not be passed back to the
onPreResponse
extension method to prevent an infinite loop.
一个简单的例子:
server.ext('onPreResponse', function (request, reply) {
if (request.response.statusCode === 400 ){
return reply('summat else');
}
return reply.continue();
});
有两个简单的解决方案:
1。使用 server.ext('onPreResponse' ...
正如@Clarkie 所指出的,在您的 Hapi 应用程序中捕获 所有 错误的 通用 方法是使用 'onPreResponse'
。
我们写了一个 Hapi 插件,它就是这样做的:https://www.npmjs.com/package/hapi-error
和往常一样:
并允许您通过 3 个简单的步骤定义自己的自定义错误页面。
1。从 npm:
安装 pluginnpm install hapi-error --save
2。在你的 Hapi 项目中包含插件
当您 register
您的服务器时包含插件:
See: /example/server_example.js for simple example
3。确保您有一个名为 error_template
的视图
Note:
hapi-error
plugin expects you are usingVision
(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生成的错误tilestatusCode
- *HTTP statusCode 发送给客户端例如:404
(未找到)errorMessage
- human-friendly 错误信息
for an example see:
/example/error_template.html
就是这样!
2。使用 failAction
我们添加了 failAction
其中 re-uses register_handler
以便 registration-form.html
显示任何输入验证错误消息(直到提交有效数据)
{
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)
})
}
}
See: server.js:57 for complete file.
其中 extract_validation_error(error)
和 return_form_input_values(error)
是在 server.js
中定义的辅助函数( 但会拆分成 re-useable 视图助手 ),这使我们的处理函数保持精简。
当我们提交没有任何必填字段的表单时,我们看到:
我们也用https://github.com/chriso/validator.js 减轻 Cross Site Scripting 漏洞:
并在注册成功时显示欢迎信息:
结论
我们认为 re-using 处理函数作为 failAction
将与此 route/action 相关的代码保存在一个地方
而 server.ext('onPreResponse' ...
(虽然适合初始检查)将引入“hooks”
可能会造成混淆(一旦一个应用有很多这样的钩子...)