首页 > 解决方案 > Hapi v17 - 文件响应的 Joi 模式

问题描述

如何为作为响应发送的文件编写 Joi 架构?

我的路线返回这个 return h.file(filename, { mode: 'attachment'}).code(201);,而且content-dispostion响应头是attachment; filename=entries.csv.

我也许可以检查发出的响应的对象结构,但是有没有办法 Joi 提供一个属性来检查响应中的文件?

这是您可能想要跟踪的 Github 问题

标签: javascripthapijscontent-dispositionjoi

解决方案


我误解了这个问题——它是关于验证响应头,而不是请求头。简短的回答:这是不可能的。

长答案:

基于hapijs 17.5.3 https://hapijs.com/api#-routeoptionsresponseoptions似乎可以使用以下功能:

server.route({
    method: 'GET',
    path: '/file',
    options: {
        handler: (request, h) => {

            return h.file('foobar.csv', { mode: 'attachment'}).code(201);
        },
        response: {
            schema: async (value, options) => {

                console.log('validating response:', value);
            }
        }
    }
});

但这种方法行不通。hapijs 不支持它,你会从第 151 行得到一个例外:https://github.com/hapijs/hapi/blob/76fcd7fa97747c92501b912d64db459d7172cb26/lib/validation.js 是:

if (!response.isBoom &&
    request.response.variety !== 'plain') {

    throw Boom.badImplementation('Cannot validate non-object response');
}

以下是验证请求标头的方法:

'use strict';
const Joi = require('joi');
const ErrorHandler = require('../handlers/errorHandler');

const fileUploadValidator = {
    config: {
        validate: {
            params: {
                env: Joi.string().min(2).max(10).required()
            },
            query: {
                id: Joi.number().integer().min(0).required()
            },
            headers: Joi.object({
                'x-request-id': Joi.string().guid().required(),
                'content-disposition': Joi.string().regex(/attachment;\s*filename=.+\.csv/gi).insensitive().required()
            }).options({ allowUnknown: true }),
            failAction: ErrorHandler.apply_genericHandler
        }
    }
};

module.exports = fileUploadValidator;

路线定义:

server.route({
    method: 'POST',
    path: '/{env}/v1/fileUpload',
    handler: FileUploadHandler.apply,
    options: FileUploadValidator.config
});

你可能需要稍微调整一下。我已经根据您的问题构建了它。


推荐阅读