【问题标题】:Validating JSON query string as query param using Joi使用 Joi 验证 JSON 查询字符串作为查询参数
【发布时间】:2016-07-07 15:34:21
【问题描述】:

我在 GET 请求查询参数中作为序列化字符串传递的验证 JSON 存在问题。

我需要实现的是将这个序列化的字符串解析回 JSON 并使用 Joi 对其进行验证。

示例:Give 是 JSON

{
 limit: {size:10, page:0},
 filter: {filter_by: 'foo', filter_val: 'foo', from: '1/1/2016',to: '1/1/2016' }
}

而这个 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

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

 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(),
            }
        }

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

【问题讨论】:

    标签: json validation hapijs joi


    【解决方案1】:

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

    Hapi 版本≥18

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

    哈比版≤17

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

    这是request.setUrl()方法下的discussed a little bit in the API docs

    【讨论】:

    • 正是我想要的。谢谢,
    • 我认为你可以对 request.query 使用 Qs 而不必担心 URL - 即Qs.parse(request.query)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 2021-09-24
    相关资源
    最近更新 更多