代码之家  ›  专栏  ›  技术社区  ›  Juned Ansari

错误:在将头发送到中间件进行joi验证后,无法设置头

  •  0
  • Juned Ansari  · 技术社区  · 7 年前

    我已经为joi验证错误处理创建了一个中间件,但是它返回一些警告,比如

    错误:

    Error: Can't set headers after they are sent.
        at validateHeader (_http_outgoing.js:491:11)
        at ServerResponse.setHeader (_http_outgoing.js:498:3)
        at ServerResponse.header (D:\nodejs\bigfish\node_modules\express\lib\response.js:767:10)
        at ServerResponse.send (D:\nodejs\bigfish\node_modules\express\lib\response.js:170:12)
        at ServerResponse.json (D:\nodejs\bigfish\node_modules\express\lib\response.js:267:15)
        at Object.JSONResponse [as JR] (D:\nodejs\bigfish\helpers\JsonResponse.js:3:29)
        at module.exports (D:\nodejs\bigfish\middlewares\error.js:8:14)
        at newFn (D:\nodejs\bigfish\node_modules\express-async-errors\index.js:12:20)
        at Layer.handle_error (D:\nodejs\bigfish\node_modules\express\lib\router\layer.js:71:5)
        at trim_prefix (D:\nodejs\bigfish\node_modules\express\lib\router\index.js:315:13)
    

    const express = require('express');
    const Joi = require('joi');
    const router = express.Router();
    const HelperJoi = require('../helpers/joivalidation');
    router.get('/GetRetailerDetails',VerifyToken, async (req,res) => {
        //Start Validation Code
        const schema = {
            RetailerId: Joi.number().required(),
        };
        HelperJoi.validate(req,res,schema);
        //End of Validation code      
    });
    

    在helpers文件夹下

    const Joi = require('joi');
    //This is Helper Function Module for Joi Validation
    function JoiValidation(req,res,schema){
        const result = Joi.validate(req.query,schema, { abortEarly: false });
        if(result.error){
            //422 Validation Error
            var objError = [];    
            Object.keys(result.error.details).forEach(function(key) {
                objError.push(result.error.details[key]['message']);
            });
            return res.status(422).json({
                'statuscode': 422,
                'message': 'Validation Error',
                'responsedata': objError
            });
        }
    }
    
    module.exports.validate = JoiValidation
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   robertklep    7 年前

    验证程序函数在出现错误时返回响应并不意味着其余代码没有运行。

    例如:

    // middleware
    if (! HelperJoi.validate(req,res,schema)) {
      // Validation failed, so we're done
      return;
    }
    
    // validator function
    if (result.error) {
      ...
      res.status(422).json({
        'statuscode': 422,
        'message': 'Validation Error',
        'responsedata': objError
      });
      return false;
    }
    return true;
    

    另一种解决方案是,验证程序函数要么在验证为正时返回“null”,要么在验证失败时返回错误数组,中间件将返回422响应本身。这将使验证器功能解耦。

        2
  •  0
  •   Tarek Essam    7 年前

        3
  •  0
  •   IftekharDani    7 年前

    看起来你的实现是错误的。

    示例:如何实施 JOI 验证

    const express = require('express');
    const router = express.Router();
    const joiHelper = require('../helpers/joiHelper');
    router.get('/GetRetailerDetails',VerifyToken, async (req,res) => {
    
       let validationResult = joiHelper.JoiValidation(req.query, joiHelper.getRetailSchema(), {allowUnknown: false});
        if (validationResult.error) {
          return res.status(422).json({
                'statuscode': 422,
                'message': 'Validation Error',
                'responsedata': joiHelper.parseError(validationResult.error.details)
            });
        }    
    
        //Proceeds your get request
    });
    

    const Joi = require('joi');
    
    const joiHelper = {};
    
    joiHelper.JoiValidation(object, schema, options = {}){
        return Joi.validate(object, schema, options);
    };
    
    joiHelper.parseError(errorObject) {
        let errorDetail = [];
        for (var key in errorObject) {
          errorDetail.push(errorObject[key].message);
        }
        return errorDetail.join(', ').replace(new RegExp('"','g'),'');
    }
    joiHelper.getRetailSchema () {
      const schemaObj = {
        RetailerId: Joi.number().required()
      };
      return Joi.object().keys(schemaObj);
    };
    
    module.exports = joiHelper;
    
    推荐文章