【问题标题】:How to avoid Hapi.js sending 400 error when Validating Request with Joi使用 Joi 验证请求时如何避免 Hapi.js 发送 400 错误
【发布时间】:2015-12-30 02:32:55
【问题描述】:

使用 Joi + failAction 问题进行 H​​api.js 验证。

情况

我们想构建一个“传统服务器端- 使用 Hapi 呈现应用程序。

我试图理解如何避免返回“raw400 Joi 验证时客户端出错失败

我们要截取这个“email not allowed to be empty验证错误,并在html模板中显示回客户端, 而不是简单地返回 400 错误。

@AdriVanHoudt 建议我们应该:

"查看http://hapijs.com/api#route-options下的failAction"

所以我们将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!');
}

我希望在终端/控制台中看到错误 但是当我尝试console.log handler 时:

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

我在 GitHub 上问了这个问题:https://github.com/hapijs/joi/issues/725 但还没有得到 例子的答案。 如果您有时间提供帮助,请提供完整代码:https://github.com/nelsonic/hapi-validation-question

【问题讨论】:

    标签: javascript node.js validation server hapijs


    【解决方案1】:

    您应该考虑在 onPreResponse extension point 中实现错误处理程序。

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

    一个简单的例子:

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

    【讨论】:

    • server.ext('onPreResponse' ... 无疑是拦截验证错误的好方法,但我们决定遵循 Matt Harrison 的建议并使用failAction。感谢您的回答! :-)
    【解决方案2】:

    两个简单的解决方案:

    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你的服务器时包含插件:

    简单例子见:/example/server_example.js

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

    注意:hapi-error 插件 预计您正在使用 VisionHapi 应用程序的标准视图渲染库) 它允许您在模板中使用 Handlebars、Jade、React 等。

    您的error_template.htmlerror_template.exterror_template.jsx)应该使用将要传递的三个变量:

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

    示例见:/example/error_template.html

    就是这样

    2。使用failAction

    我们添加了failAction,它重复使用 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)
        })
      }
    }
    

    有关完整文件,请参阅:server.js:57

    extract_validation_error(error)return_form_input_values(error) 是在server.js 中定义的辅助函数(但会被拆分为可重复使用的视图辅助函数),它们使我们的处理函数保持精简。

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

    我们也使用https://github.com/chriso/validator.js 减轻Cross Site Scripting 漏洞:

    并在成功注册时显示欢迎消息:

    结论

    我们觉得重新使用处理函数作为failAction 将与此路线/操作相关的代码保存在一个地方 而server.ext('onPreResponse' ...在初步检查时合适)将引入“钩子” 这可能会造成混乱(一旦应用程序有许多这样的钩子......

    #YMMV

    让我们知道您的想法!

    【讨论】:

      猜你喜欢
      • 2020-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 2017-07-22
      • 2016-01-06
      • 2019-05-05
      相关资源
      最近更新 更多