1. 程式人生 > >舉例:NodeJs Resify請求引數驗證

舉例:NodeJs Resify請求引數驗證

在使用restify實現webapi時常常會遇到獲取和驗證請求引數的問題,與.NET、JAVA等程式語言有確定型別不同,JavaScript這類指令碼語言輸入引數並沒有明確的型別,如果獲取失敗會返回undefined,當輸入引數有多個欄位時,單純依靠傳統判斷方式不僅麻煩而且容易遺漏不容易維護,故而將驗證流程統一成為可複用方法是比較好的選擇。

首先需要定義輸入引數的範圍,即輸入引數的格式。一般情況下,我們採用application/json格式。以使用者註冊為例,以下羅列一些使用者註冊時的引數:

const defaultParams = {
  username: {
    type: 'string',
    required: true,
  }, // 使用者名稱
  password: {
    type: 'string', allowNull: true,
  }, // 密碼MD5格式
  mobile: { type: 'string', allowNull: true }, // 手機號
  email: { type: 'string', allowNull: true }, // 郵箱
  gender: {
    type: 'int',
    allowNull: true,
    validate: src => [0, 1, 2].indexOf(src) >= 0,
  }, // 性別(0-未知,1-男,2-女)
  birthday: { type: 'datetime', allowNull: true }, // 生日
  zipcode: { type: 'string', allowNull: true }, // 郵編
  nickname: { type: 'string', allowNull: true } // 暱稱
};

其中type欄位型別,allowNull是否允許欄位缺失,required是否必要,validate驗證條件。下面就要從post資料體內獲取需要的資料。

const getParams = (params, defaultParams) => {
  const result = {};
  const keys = Object.keys(defaultParams);
  for (let i = 0, len = keys.length; i < len; i += 1) {
    result[keys[i]] = typeof params[keys[i]] === 'string' ? params[keys[i]].trim() : params[keys[i]];
  }
  return result;
};

獲取資料後就可以進行驗證了,我們可以對於不同的資料型別進行統一的處理。

const validate = {
  string: src => (typeof src === 'string'),
  int: src => (typeof src === 'number' && src % 1 === 0),
  float: src => (typeof src === 'number'),
  datetime: (src) => {
    const time = moment(src, dateFormat);
    const result = validate.string(src)
      && time.isValid()
      && time.format(dateFormat).split(' ').join('') === src.split(' ').join('');
    return result;
  },
  mobile: (src) => {
    const reg = /^1[3|4|5|7|8][0-9]{9}$/;
    const result = validate.string(src) && reg.test(src);
    return result;
  },
  email: src => (validate.string(src) && validator.isEmail(src)),
};
 


const validateParams = (params, paramsTemplate) => {
  let errCode = rtCode.paramsErr;
  const keys = Object.keys(paramsTemplate);
  for (let i = 0, len = keys.length; i < len; i += 1) {
    if (paramsTemplate[keys[i]].required) {
      if (params[keys[i]] === undefined || params[keys[i]] === null) {
        return { errCode: rtCode.dataLost, msg: `${keys[i]} is required.` };
      }
      if (params[keys[i]] === '') {
        errCode = paramsTemplate[keys[i]].errCode || rtCode.paramsErr;
        return { errCode, msg: `${keys[i]} can't be empty string.` };
      }
    }
    if (params[keys[i]] !== undefined) {
      if (
        !(paramsTemplate[keys[i]].allowNull && params[keys[i]] === null)
        && !validate[paramsTemplate[keys[i]].type](params[keys[i]])
      ) {
        return { errCode, msg: `${keys[i]} must is ${paramsTemplate[keys[i]].type}.` };
      }
      if (
        !(paramsTemplate[keys[i]].allowNull && params[keys[i]] === null)
        && paramsTemplate[keys[i]].validate
        && !paramsTemplate[keys[i]].validate(params[keys[i]])
      ) {
        errCode = paramsTemplate[keys[i]].errCode || rtCode.paramsErr;
        return { errCode, msg: `${keys[i]} is not match.` };
      }
    }
  }
  return { errCode: rtCode.success };
};

好了,以上就完成所有的驗證步驟了。