Hapi.js 是一个基于 Node.js 平台的 web 框架,它提供了丰富的插件系统和强大的路由控制,使得开发者能够更快速、更方便地构建高性能的 web 应用程序。在本文中,我们将分享一些 Hapi.js 常用插件及使用技巧,以帮助大家更好地使用这个框架。
常用插件
hapi-auth-jwt2
hapi-auth-jwt2 是一款用于 Hapi.js 的 JWT 鉴权插件。使用 JWT(JSON Web Token)作为身份验证方式,可以使身份信息在跨域传输过程中更加安全。hapi-auth-jwt2 插件提供了一个策略定义的方式,使得开发者可以很容易地定义和使用多个不同的鉴权策略。
以下是一个使用 hapi-auth-jwt2 插件的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const Jwt = require('jsonwebtoken'); const HapiAuthJwt2 = require('hapi-auth-jwt2'); const server = new Hapi.Server(); server.connection({ port: 3000 }); const jwtKey = 'my_secret_key'; server.register(HapiAuthJwt2, (err) => { if (!err) { server.auth.strategy('jwt', 'jwt', { key: jwtKey, validateFunc: (decoded, request, callback) => { // decoded 是 JWT 解码后的内容,request 是当前请求对象 // 返回 callback(null, true) 表示验证通过 if (decoded.username === 'user' && decoded.password === 'password') { callback(null, true); } else { callback(null, false); } } }); } }); server.route({ method: 'GET', path: '/protected', config: { auth: 'jwt' }, handler: (request, reply) => { reply('Hello, protected!'); } }); server.start((err) => { console.log('Server started at:', server.info.uri); });
在这个示例代码中,我们首先定义了一个 JWT 密钥 jwtKey
,然后在服务器注册 hapi-auth-jwt2 插件,并定义了一个名为 jwt
的鉴权策略,其中的 validateFunc
回调函数用于验证 JWT 携带的信息是否正确。最后,在某个需要被鉴权的路由中,我们使用 auth: 'jwt'
参数指定该路由需要进行 JWT 鉴权。
hapi-swagger
hapi-swagger 是一款基于 OpenAPI 标准的 API 文档生成插件。使用 hapi-swagger 插件,我们可以很方便地生成 API 文档,并提供一个可交互的 UI 界面,使得开发者可以轻松地查看和测试 API 接口。
以下是一个使用 hapi-swagger 插件的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const Inert = require('inert'); const Vision = require('vision'); const HapiSwagger = require('hapi-swagger'); const server = new Hapi.Server(); server.connection({ port: 3000 }); const swaggerOptions = { info: { title: 'Test API Documentation', version: '1.0.0' } }; server.register([ Inert, Vision, { register: HapiSwagger, options: swaggerOptions } ], (err) => { if (err) { console.error('Failed to load plugin:', err); } }); server.route({ method: 'GET', path: '/hello', config: { tags: ['api'], description: 'Say hello to the world', handler: (request, reply) => { reply('Hello, world!'); }, plugins: { 'hapi-swagger': { responses: { '200': { description: 'Successful response', schema: Hapi.types.String() } } } } } }); server.start((err) => { console.log('Server started at:', server.info.uri); });
在这个示例代码中,我们首先定义了一些 Swagger 文档生成的参数,如 API 标题和版本号等。然后,我们在服务器注册 necessary 的插件 Inert 和 Vision 以及 hapi-swagger 插件,并传入相关的参数对象。最后,在路由里,我们使用 tags
和 description
参数定义了该 API 的标签和描述,使用 plugins
参数为该路由指定了 Swagger 文档中应该包含的响应数据结构。
hapi-rate-limit
hapi-rate-limit 是一款基于 IP 地址的限流插件。使用 hapi-rate-limit 插件,我们可以限制指定 IP 地址的访问频率,防止恶意攻击或者刷接口。
以下是一个使用 hapi-rate-limit 插件的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const HapiRateLimit = require('hapi-rate-limit'); const server = new Hapi.Server(); server.connection({ port: 3000 }); const ratelimitOptions = { userLimit: 5, userCache: { expiresIn: 5000 } }; server.register({ register: HapiRateLimit, options: ratelimitOptions }, (err) => { if (err) { console.error('Failed to load plugin:', err); } }); server.route({ method: 'GET', path: '/hello', handler: (request, reply) => { reply('Hello, world!'); } }); server.start((err) => { console.log('Server started at:', server.info.uri); });
在这个示例代码中,我们首先定义了一个限流配置对象 ratelimitOptions
,其中 userLimit
参数限制了每个 IP 地址能够在多长时间内访问多少次,而 userCache
参数则指定了该限流规则的生命周期。然后,我们在服务器注册了 hapi-rate-limit 插件,并传入了该配置对象。最后,我们在某个路由中定义了一个响应处理函数。
使用技巧
自定义路由参数解析器
Hapi.js 中的路由参数解析是默认的字符串类型,不支持更复杂的数据类型(如数组、对象等)。如果需要自定义路由参数解析器,我们可以使用 server.route(options)
方法,其中 options
参数是由路由配置对象组成的数组,并且在每个对象中我们可以定义一个 config.parse
方法用于自定义参数解析。以下是一个使用自定义参数解析器的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const Joi = require('joi'); const server = new Hapi.Server(); server.connection({ port: 3000 }); server.route({ method: 'GET', path: '/users/{ids}', handler: (request, reply) => { reply(request.query); }, config: { validate: { params: { ids: Joi.array().items(Joi.number()) }, query: { search: Joi.string().optional() } }, parse: { params(ids) { return ids.split(','); } } } }); server.start((err) => { console.log('Server started at:', server.info.uri); });
在这个示例代码中,我们首先定义了一个路由 /users/{ids}
,其中 ids
是一个以逗号分隔的数字列表。在配置对象中,我们使用 validate
参数对参数进行了校验,使用 parse.params
方法定义了一个解析逗号分隔的字符串的函数。最后,我们在响应处理函数中直接输出了请求的查询参数。
使用 reply.file() 响应文件下载请求
在 Hapi.js 中,使用 reply
方法响应请求时可以直接输出一个文件并让浏览器或者客户端进行下载。使用 reply.file(filename)
方法,则可以输出一个存储在服务器本地的文件。以下是一个使用 reply.file()
响应文件下载请求的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const Path = require('path'); const server = new Hapi.Server(); server.connection({ port: 3000 }); server.route({ method: 'GET', path: '/download', handler: (request, reply) => { const path = Path.join(__dirname, 'file.txt'); reply.file(path, { filename: 'my_file.txt', mode: 'attachment' }); } }); server.start((err) => { console.log('Server started at:', server.info.uri); });
在这个示例代码中,我们首先定义了一个路由 /download
,在响应处理函数中调用 reply.file()
方法输出服务器中的文件 file.txt
。其中,我们使用 filename
参数指定了下载文件的名称,使用 mode
参数指定了浏览器打开文件时的行为(attachment
表示下载)。
总结
本文介绍了一些 Hapi.js 常用插件及使用技巧,包括 hapi-auth-jwt2、hapi-swagger、hapi-rate-limit 插件以及自定义路由参数解析器、使用 reply.file()
方法输出文件下载请求等技巧。这些技术点在实际的开发过程中都有非常实用的价值,帮助我们更好地进行 web 应用程序的开发和部署。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/652cdfc07d4982a6ebe6a1b2