使用Joi将JSON查询字符串验证为查询参数

Bad*_*adr 5 validation json hapijs joi

我有一个验证JSON的问题,它在GET请求查询参数中作为序列化字符串传递.

我需要实现的是将此序列化字符串解析回JSON并使用Joi验证它.

示例:Give是JSON

{
 limit: {size:10, page:0},
 filter: {filter_by: 'foo', filter_val: 'foo', from: '1/1/2016',to: '1/1/2016' }
}
Run Code Online (Sandbox Code Playgroud)

而这个JSON转换为查询字符串是:

limit%5Bsize%5D=10&limit%5Bpage%5D=0&filter%5Bfilter_by%5D=foo&filter%5Bfilter_val%5D=foo&filter%5Bfrom%5D=1%2F1%2F2016&filter%5Bto%5D=1%2F1%2F2016
Run Code Online (Sandbox Code Playgroud)

我需要这样的东西来检查:

 validate: {
          query: {
            limit: Joi.someMethodToGetJsonFromString.object().keys({
              size: Joi.number(),
              page: Joi.number()
            }
          filter: Joi.someMethodToGetJsonFromString,.object().keys({
              filter_by: Joi.string().valid(['option1', 'option2']),
              filter_val: Joi.string(),
              from: Joi.date(),
              to: Joi.date(),
            }
        }
Run Code Online (Sandbox Code Playgroud)

Joi中有什么可以帮助在这种情况下,或者我需要为它编写自定义验证函数.

Mat*_*son 4

您需要更换所使用的查询字符串解析,因为 hapi 默认情况下不支持该格式。它只是使用 Node 的内置url模块来解析 URL,不支持查询字符串的复杂编码。您需要使用 手动解析它qs,之后您可以正常进行验证。

\n

Hapi版本\xe2\x89\xa518

\n

您可以通过server.options.query.parser设置自定义解析器。

\n

Hapi 版本 \xe2\x89\xa417

\n
const Hapi = require(\'hapi\');\nconst Joi = require(\'joi\');\nconst Url = require(\'url\');\nconst Qs = require(\'qs\');\n\nconst server = new Hapi.Server();\nserver.connection({ port: 4000 });\n\nconst onRequest = function (request, reply) {\n\n    const uri = request.raw.req.url;\n    const parsed = Url.parse(uri, false);   // skip the querystring parsing\n    parsed.query = Qs.parse(parsed.query);  // parse it ourselves with qs\n    request.setUrl(parsed);\n\n    return reply.continue();\n};\n\nserver.ext(\'onRequest\', onRequest);\n\nserver.route({\n    config: {\n        validate: {\n            query: {\n                limit: Joi.object().keys({\n                    size: Joi.number(),\n                    page: Joi.number()\n                }),\n                filter: Joi.object().keys({\n                    filter_by: Joi.string().valid([\'option1\', \'option2\']),\n                    filter_val: Joi.string(),\n                    from: Joi.date(),\n                    to: Joi.date(),\n                })\n            }\n        }\n    },\n    method: \'GET\',\n    path: \'/\',\n    handler: function (request, reply) {\n\n        return reply(\'ok\');\n    }\n});\n\nserver.start((err) => {\n\n    if (err) {\n        throw err;\n    }\n    console.log(\'Started server\');\n});\n
Run Code Online (Sandbox Code Playgroud)\n

API 文档中该方法下对此进行了一些讨论request.setUrl()

\n