返回介绍

Lifecycle methods

发布于 2024-02-12 19:53:56 字数 7553 浏览 0 评论 0 收藏 0

生命周期方法是框架和应用程序之间的接口。 许多请求生命周期步骤: extensions , authentication , handlers , pre-handler methods , 和 failAction function values 是由开发人员提供并由框架执行的生命周期方法。

每个生命周期方法都是一个带有签名 await function(request, h, [err]) 函数,其中:

  • request - request object .
  • h - response toolkit 处理程序必须调用以设置响应并将控制权返回给框架。.
  • err - 仅当该方法用作 failAction value 是才可用的错误对象。

每个生命周期方法都必须返回一个值或一个解析为值的 promise。如果生命周期方法返回没有值或解析为 undefined 值, an Internal Server Error (500) 错误

返回值必须是以下之一

  • 基本值:
    • null
    • string
    • number
    • boolean
  • Buffer 对象
  • Error 对象
    • 基本的 Error .
    • Boom 对象.
  • Stream 对象
    • 必须与 "streams2" API 兼容,而不是在 objectMode
    • 如果流对象具有 statusCode 属性, 该状态代码将用作基于 passThrough 选项的默认响应代码。
    • 如果流对象具有 headers 属性,, 头部将根据 passThrough 选项包含在响应中。
    • 如果流对象具有函数属性 setCompressor(compressor) 并且响应通过压缩器,压缩器流的引用将通过此方法传递给响应流。
  • 任意对象或数组
    • 不得包含循环引用。
  • 工具包签名:
    • h.abandon - 中止处理请求。
    • h.close -中止处理请求并调用 end() 以确保响应被关闭。
    • h.continue - 继续处理请求生命周期而不更改响应。
  • 工具包方法响应:
    • h.response() - 通过 response object 包装一个简单的响应.
    • h.redirect() - 使用重定向指令包装一个简单的响应。
    • h.authenticated() - 表示请求已成功验证 (auth scheme only).
    • h.unauthenticated() - 表示请求无法进行身份验证 (auth scheme only).
  • 一个 promise 对象,可以解析为上述任何值

生命周期方法抛出的任何错误都将用作响应对象。 虽然可以返回错误和有效值,建议抛出错误。 抛出非错误值 Bad Implementation (500) 的错误响应。

const handler = function (request, h) {

  if (request.query.forbidden) {
    throw Boom.badRequest();
  }

  return 'success';
};

如果路由使用 bind 选项或者 server.bind() 被调用, 生命周期方法将通过 this 绑定到提供的上下文,也可以通过 h.context 访问。

Lifecycle workflow

每个生命周期步骤之间的流程取决于每个生命周期方法返回的值,如下所示:

  • an error:

    • 生命周期跳到 Response validation 阶段.
    • 如果被 onRequest 阶段返回, 将跳到 onPreResponse 阶段.
    • 如果 Response validation 阶段返回, 将跳到 onPreResponse 阶段.
    • 如果 onPreResponse 阶段返回, 将跳到 Response transmission 阶段.
  • 一个终止信号 ( h.abandonh.close ):

    • 跳到 Finalize request 阶段.
  • 一个 h.continue 信号:

    • 继续处理请求生命周期而不更改请求响应。
    • 不能被 authenticate() 方法使用
  • takeover response :

    • 使用提供的值覆盖请求响应,并跳到 Response validation 阶段。
    • 如果被 Response validation 阶段返回, 将跳到 onPreResponse 阶段。
    • 如果被 onPreResponse 阶段返回,将跳到 Response transmission 阶段。
  • 任何其他的响应:

    • 使用提供的值覆盖请求响应,并继续处理请求生命周期。
    • 无法从 _Pre-handler methods 阶段之前的任何步骤返回。

authenticate() 方法可以访问两个额外的返回值: - h.authenticated() - 表示请求已成功验证。 - h.unauthenticated() - 表示请求验证失败。

请注意,在 pre-handler method 中使用时,这些规则的应用有所不同。

Takeover response

接替响应 response objectresponse.takeover() 被调用签名 lifecycle method 的返回值。应设置为响应并跳过以立即验证和传输值, 绕过其他生命周期步骤。

failAction 配置

各种配置选项允许定义错误的处理方式。 例如,当收到无效的有效负载或格式错误的 cookie 时,而不是返回错误,框架可以配置为执行另一个操作。 当支持 failAction 选项时, 支持以下值:

  • 'error' - 将错误对象作为响应返回。

  • 'log' - 报告错误但继续处理请求。

  • 'ignore' - 不采取任何行动并继续处理请求。

  • lifecycle method 带有签名函数 async function(request, h, err) :

    • request - request object .
    • h - response toolkit .
    • err - 错误对象。

Errors

hapi 使用 boom 错误第三方库去显示内部的错误生成. boom 提供了一个表达式接口来返回 HTTP 错误. lifecycle method 抛出的任何错误都将转换为 boom 对象,如果错误不是 boom 对象, 默认为 500 状态码。

当错误发送回客户端时,response 包含一个带有 statusCode , error , 和 message 键的 JSON 对象。

const Hapi = require('hapi');
const Boom = require('boom');

const server = Hapi.server();

server.route({
  method: 'GET',
  path: '/badRequest',
  handler: function (request, h) {

    throw Boom.badRequest('Unsupported parameter');   // 400
  }
});

server.route({
  method: 'GET',
  path: '/internal',
  handler: function (request, h) {

    throw new Error('unexpect error');          // 500
  }
});

Error transformation

可以通过更改其 output 内容来自定义错误。boom 错误对象包含以下属性:

  • isBoom - 如果是 true , 表示【indicates】这是一个 Boom 对象实例。

  • message - 错误信息.

  • output - 格式化的 response. 可以在对象构造后直接操作返回自定义错误响应. 允许的根节点:

    • statusCode - HTTP 状态码 (typically 4xx or 5xx).

    • headers - 包含任何 HTTP 头的对象,其中每个键都是 header 名称,值是 header 内容。

    • payload - 用作响应有效负载的格式化对象 (字符串化). 可以直接操作,但如果调用 reformat() , 任何更改都将丢失。 允许的任何内容,默认情况下包括以下内容:

      • statusCode - HTTP 状态码, 派生于 error.output.statusCode .

      • error - 派生自 statusCode` 的错误信息 (例如 'Bad Request', 'Internal Server Error')。

      • message - 派生自【derived from】 error.message 的错误信息。

  • 继承 Error 属性.

它还支持以下方法:

  • reformat() - 使用其他对象属性重新构建 error.output .
const Boom = require('boom');

const handler = function (request, h) {

  const error = Boom.badRequest('Cannot feed after midnight');
  error.output.statusCode = 499;  // Assign a custom error code
  error.reformat();
  error.output.payload.custom = 'abc_123'; // Add custom key
  throw error;
});

当需要不同的错误表示时, 例如 HTML 页面或不同的 payload 格式, 'onPreResponse' 扩展点可以用于识别错误并且用不同的 response 对象替换它们, 就像在这个例子中使用 Vision's .view() response toolkit 属性.

const Hapi = require('hapi');
const Vision = require('vision');

const server = Hapi.server({ port: 80 });
server.register(Vision, (err) => {
  server.views({
    engines: {
      html: require('handlebars')
    }
  });
});

const preResponse = function (request, h) {

  const response = request.response;
  if (!response.isBoom) {
    return h.continue;
  }

  // Replace error with friendly HTML

    const error = response;
    const ctx = {
      message: (error.output.statusCode === 404 ? 'page not found' : 'something went wrong')
    };

    return h.view('error', ctx).code(error.output.statusCode);
};

server.ext('onPreResponse', preResponse);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文